如果我有Struct
或Class
,请假设我使用的是Vector2(有两个成员,float X
和float Y
),我应该在课堂上正确获取/设置方法吗?
这是我现在所知道的代码:
public class MyClass
{
private Vector2 vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
但是,如果我想使用Vector2
方法编辑set
的成员(或某些成员)呢?像我这样的东西是我要求的:
set.X
{
vector.X = value.X;
}
set.Y
{
vector.Y = value.Y;
}
它将被称为Vector.X = 5
。我想了一个替代方案,使用像public float VectorX { set { vector.X = value; } }
这样的东西,但我更喜欢更符合逻辑和面向对象的方式。有吗?
答案 0 :(得分:1)
Vector2
是一个类还是一个结构,这有很大的不同。
由于Vector2
是一个类,您可以简单地执行
obj.Vector.X = 5;
具有
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
但是,如果Vector2
是结构,那么您无法修改get
的返回值。如果您尝试,将收到编译错误:
无法修改...的返回值,因为它不是变量。
您可以使用
建议的方法解决此问题public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
或者您可以在Vector2
周围提供一个包装类,如:
class Vector2Wrapper
{
public Vector2 Vector;
}
然后将Vector2Wrapper
存储在MyClass
中
public class MyClass
{
private Vector2Wrapper _vector2Wrapper;
public Vector2Wrapper VectorWrapper
{
get { return _vector2Wrapper; }
set { _vector2Wrapper= value; }
}
}
然后您可以像
一样修改它obj.VectorWrapper.Vector.X = 5;
答案 1 :(得分:0)
您无法指定处理该部分集的子方法,因为该集由Vector
类处理,因此我们超出了您的范围。当有人打电话给Myobject.Vector
他们正在调用你的函数时,但当它移动到.X
时,他们正在调用Vector.get_X
函数。
通过使用ILDasm工具查看已编译的代码可能会更容易看到这一点,该工具会显示实际的方法调用,您的属性会产生糖。
现在,您可以做的是 wrap 某些属性,如上所述。结果就是这样。
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
}
另一种选择可能是在Vector类中使用INotifyPropertyChanged的模式,每次更改都会引发一个事件,然后MyClass可以监听并做出反应,从而在更新子元素时应用逻辑。
还可以选择使用索引器属性
public class MyClass
{
public enum Axis { X, Y }
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float this[Axis axis]
{
get { return axis == Axis.X ? vector.x : vector.y; }
set
{
if(axis == Axis.Y)
{
// Special logic here
vector.Y = value;
}
if(axis == Axis.X)
{
// Special logic here
vector.X = value;
}
}
}
}
答案 2 :(得分:0)
因为Vector2是一个结构,所以你得到一个COPY。您需要使用setter来设置新的Vector2。有两种方式:
Vector2 v = myClass.Vector; //get a copy of the vector
v.X = 5f; // change its value
myClass.Vector = v; // put it back
我不太喜欢以下内容,但这只是一个声明:
myClass.Vector = new Vector2(2f, myClass.Vector.Y)
在MyClass中,您可以创建一个仅设置X值的属性:
public float X {
get { return Vector.X; }
set {
Vector2 v = Vector;
v.X = value;
Vector = v;
}
}
(矢量可以是自动属性)