扩展方法无意中复制参数
extension methods unintentionally copying argument
我无法使用扩展方法,它会 运行,但我作为参数放入其中的 Vector3 与我在 TurnClockWiseXZ 方法中操作的矢量不同。
这是class调用方法。
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
void FixedUpdate () {
Vector3 test = new Vector3(2,0,3);
Debug.Log ("1: "+test);
test.TurnClockWiseXZ();
Debug.Log ("2: "+test);
}
}
这是我添加方法的地方:
using UnityEngine;
using System.Collections;
public static class ExtendClass {
public static void TurnClockWiseXZ( this Vector3 vector){
float x = vector.z;
float y = vector.y;
float z = -vector.x;
vector.Set(x,y,z);
}
}
这是我得到的调试信息:
1: (2.0, 0.0, 3.0)
2: (2.0, 0.0, 3.0)
这就是我想要的:
1: (2.0, 0.0, 3.0)
2: (3.0, 0.0, -2.0)
不幸的是,因为 Vector3 是一个 struct(因此是一个 value 类型),它总是通过创建一个复制 本身(按值传递)。因此,扩展方法内的任何修改只会影响副本。
我看到了一些替代方案。
1) 使您的扩展方法 return 成为 new 复制的向量并重置外部变量。调用时看起来像这样:test = test.TurnClockwiseXZ();
2) 改用 return 无效的静态方法(不是扩展方法),但将向量作为 ref
参数。所以它看起来像这样: ExtendClass.TurnClockwiseXZ(ref test);
定义是 public void TurnClockwiseXZ(ref Vector3 vect)
这通过引用传递向量,所以它修改了函数内部的外部变量。
3) 如果您大部分时间只是修改变换内部的位置(就像我一样),那么您可以让扩展方法直接对变换进行操作。因为转换是 class(而不是结构),所以默认情况下它通过引用传递并且扩展方法可以工作。该解决方案如下所示:
public void TurnClockwiseXZ(this Transform transform) {
float x = transform.position.z;
float y = transform.position.y;
float z = -transform.position.x;
transform.position = new Vector3(x,y,z);
}
并用作:transform.TurnClockwiseXZ();
我个人在transform上有SetX、SetY、SetZ的扩展方法,方便修改位置。省去一些麻烦。
我无法使用扩展方法,它会 运行,但我作为参数放入其中的 Vector3 与我在 TurnClockWiseXZ 方法中操作的矢量不同。
这是class调用方法。
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
void FixedUpdate () {
Vector3 test = new Vector3(2,0,3);
Debug.Log ("1: "+test);
test.TurnClockWiseXZ();
Debug.Log ("2: "+test);
}
}
这是我添加方法的地方:
using UnityEngine;
using System.Collections;
public static class ExtendClass {
public static void TurnClockWiseXZ( this Vector3 vector){
float x = vector.z;
float y = vector.y;
float z = -vector.x;
vector.Set(x,y,z);
}
}
这是我得到的调试信息:
1: (2.0, 0.0, 3.0)
2: (2.0, 0.0, 3.0)
这就是我想要的:
1: (2.0, 0.0, 3.0)
2: (3.0, 0.0, -2.0)
不幸的是,因为 Vector3 是一个 struct(因此是一个 value 类型),它总是通过创建一个复制 本身(按值传递)。因此,扩展方法内的任何修改只会影响副本。
我看到了一些替代方案。
1) 使您的扩展方法 return 成为 new 复制的向量并重置外部变量。调用时看起来像这样:test = test.TurnClockwiseXZ();
2) 改用 return 无效的静态方法(不是扩展方法),但将向量作为 ref
参数。所以它看起来像这样: ExtendClass.TurnClockwiseXZ(ref test);
定义是 public void TurnClockwiseXZ(ref Vector3 vect)
这通过引用传递向量,所以它修改了函数内部的外部变量。
3) 如果您大部分时间只是修改变换内部的位置(就像我一样),那么您可以让扩展方法直接对变换进行操作。因为转换是 class(而不是结构),所以默认情况下它通过引用传递并且扩展方法可以工作。该解决方案如下所示:
public void TurnClockwiseXZ(this Transform transform) {
float x = transform.position.z;
float y = transform.position.y;
float z = -transform.position.x;
transform.position = new Vector3(x,y,z);
}
并用作:transform.TurnClockwiseXZ();
我个人在transform上有SetX、SetY、SetZ的扩展方法,方便修改位置。省去一些麻烦。