C#访问变量等值类型属性

时间:2009-06-30 22:35:07

标签: c# properties value-type

我想知道C#属性是否可以实现以下功能。

我有一个“Transform”类,它在私有成员字段中保存一个4x4矩阵。现在我想创建一个这样的属性:

    Matrix m;
    public Vector3 Position
    {
        get { return new Vector3(m[12], m[13], m[14]); }
        set { m[12] = value.X; m[13] = value.Y; m[14] = value.Z; }
    }

但我想提供以下功能:

    Transform myTransform = new Transform();
    myTransform.Position.X += 3.0f;

这样可以直接更改属性,就好像它是一个变量一样。用C#以某种方式可能吗? (Vector3和Matrix都是结构。)

谢谢!

2 个答案:

答案 0 :(得分:4)

不,这不起作用。想一想 - 你的getter和setter真的的东西。你不能在不完全改变语义的情况下绕过它们,我不会指望一个setter只是因为我改变了getter返回的内容而运行。

你真的 拥有可变结构吗?你会发现各种角落的情况和怪异。为什么不让它们变成不可变的,写一下:

myTransform.Position = myTransform.Position.OffsetBy(3.0f, 0f, 0f);

myTransform.OffSetPosition(3.0f, 0f, 0f);

这样可以避免首先构建Vector3

可变结构很少是正确的解决方案。在极少数情况下,由于性能原因,可能是合理的,但我会首先探索所有其他选项。

答案 1 :(得分:0)

正如乔恩所说,这只是一个坏主意。每当你处理简单的值类型(并且Vector3符合条件)时,你最好不要让它们成为不可变的。

如果你真的认真,你可以关闭到你想要的东西,但这需要一些工作。

public struct Vector3
{
    public Vector3(float X, float Y, float Z, VectorListener listener)
    {
        m_x = X;
        m_y = Y;
        m_z = Z;
        m_listener = listener;
    }
    private VectorListener m_listener;
    private float m_x;
    private float m_y;
    private float m_z;

    public float X
    {
        get{return m_x;}
        set{ m_x = value; m_listener.SetVector(this);}
    }
    public float Y
    {
        get { return m_y; }
        set { m_y = value; m_listener.SetVector(this); }
    }
    public float Z
    {
        get { return m_z; }
        set { m_z = value; m_listener.SetVector(this); }
    }

}
public interface VectorListener
{
    void SetVector(Vector3 vec);
}
public class Transform : VectorListener
{
    private bool m_receivedUpdate;
    public Vector3 MyVector { get{return new Vector3(1.0f, 1.0f, 1.0f, this);} }
    public void SetVector(Vector3 vec)
    {
        ReceivedUpdate = true;
    }
    public bool ReceivedUpdate { get; set; }
}

    // and the test... test class omitted for brevity
    [TestMethod]
    public void TestMethod1()
    {
        Transform transform = new Transform();
        Assert.IsFalse(transform.ReceivedUpdate);

        // the following won't compile
        //transform.MyVector.X = 3.0f;

        // but this will work
        Vector3 vec = transform.MyVector;
        vec.X = 3.0f;
        Assert.IsTrue(transform.ReceivedUpdate);

    }

话虽如此,不会这样做。我会立即拒绝任何包含此类代码的代码审核。