获取/设置C类结构或类的成员#

时间:2014-06-25 17:55:14

标签: c# class struct

如果我有StructClass,请假设我使用的是Vector2(有两个成员,float Xfloat 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; } }这样的东西,但我更喜欢更符合逻辑和面向对象的方式。有吗?

3 个答案:

答案 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;
    }
}

(矢量可以是自动属性)