在类中获取/设置结构或类的成员
本文关键字:成员 结构 获取 设置 | 更新日期: 2023-09-27 18:10:26
如果我有一个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; }
}
}
但是如果我想用set
方法编辑Vector2
的成员(或某些成员)该怎么办?这就是我想要的:
set.X
{
vector.X = value.X;
}
set.Y
{
vector.Y = value.Y;
}
它将被简单地称为Vector.X = 5
。我想到了另一种选择,使用public float VectorX { set { vector.X = value; } }
之类的东西,但我更喜欢更合乎逻辑和面向对象的方式。是吗?
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;
}
然后在MyClass
中存储Vector2Wrapper
,例如
public class MyClass
{
private Vector2Wrapper _vector2Wrapper;
public Vector2Wrapper VectorWrapper
{
get { return _vector2Wrapper; }
set { _vector2Wrapper= value; }
}
}
然后你可以把它修改成
obj.VectorWrapper.Vector.X = 5;
您不能指定一个子方法来处理该部分集合,因为该集合由Vector
类处理,因此超出了您的作用域。当有人调用Myobject.Vector
时,他们正在调用您的get函数,但是当它移动到.X
时,他们正在调用Vector.get_X
函数。
通过使用ilasm工具查看编译后的代码,这可能更容易看到,它揭示了实际的方法调用你的属性来制作糖。
现在,您可以做的是换行某些属性,如前所述。结果就像这样。
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;
}
}
}
}
因为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;
}
}
(Vector可以是一个自动属性)