2009-06-30 28 views
1

我想知道以下是否可能與C#屬性。C#訪問變量的值類型屬性

我有一個類「轉換」,在私人成員字段中保存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都是結構體。)

謝謝!

回答

4

不,這是行不通的。想一想 - 你的獲得者和制定者真的是的東西。如果不完全改變語義,你不能繞過它們,我不希望setter運行,只是因爲我改變了getter返回的內容。

你真的有可變結構開始嗎?你會發現各種各樣的角落案例和古怪。爲什麼不能讓他們一成不變的,並寫上:

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

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

這將節省您不必建立Vector3擺在首位。

可變結構是非常非常非常正確的解決方案。在極少數情況下,他們可能由於性能原因是合理的,但我會首先探索所有其他選項。

+0

你應該有營業時間,讓我們其他人知道什麼時候打擾回答問題...... D – 2009-06-30 22:43:54

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); 

    } 

這就是說,不這樣做。我會立即拒絕包含這樣的代碼的任何代碼審查。