繁体   English   中英

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

[英]Get/Set The Members of a Struct or a Class in a Class C#

如果我有一个StructClass ,可以说我正在使用Vector2(它有两个成员, float Xfloat 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; } } 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;
}

然后将Vector2Wrapper存储在MyClass例如

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函数。

通过使用ILDasm工具查看已编译的代码,这可能更容易看清,该工具揭示了属性调用的实际方法。

现在,您可以做的是包装某些属性,如上所述。 结果是这样的。

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。 您需要使用设置器来设置新的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;
    }
}

(向量可以是自动属性)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM