2012-06-19 41 views
3

如果我有:C#屬性是如何工作的?

class Test 
{ 
    private Vector2 v; 

    public Vector2 Velocity 
    { 
     get { return v; } 
     set { v = value; } 
    } 
} 

然後:

Test t = new Test(); 

t.Velocity = new Vector2(2, 2); 
t.Velocity.Normalize(); 
Console.WriteLine(t.Velocity); // here not normalized 

Vector2 tmp = t.Velocity; 
tmp.Normalize(); 
t.Velocity = tmp; 
Console.WriteLine(t.Velocity); // here normalized 

Console.Read(); 

爲什麼,如果我直接嘗試調用規範化的財產速度是不歸 並用TMP Vector2它是什麼?

P.S. Vector2是一個結構:

public struct Vector2 : IEquatable<Vector2> 
{ 
    public float X; 
    public float Y; 
    ... 
    public void Normalize() {...} 
} 
+3

Vector2似乎是一個值類型。你應該閱讀[C#概念:值與參考類型](http://www.albahari.com/valuevsreftypes.aspx) –

+0

@ noah1989那麼'tmp'將如何歸一化,因爲'tmp.Normalize()'是不是重新分配給'tmp'? –

+0

其實我們需要更多的代碼。如何定義'Test'和'Vector2'? –

回答

4

列表項

我猜你的情況Vector2是值類型(結構)。

在這種情況下,你的第一個例子,你將獲得由Velocity屬性的get部分返回v副本,你會叫Normalize上的副本,有效地無所事事,因爲副本後超出範圍對Normalize的調用。

如果Vector2是一個引用類型(類),它將按照您的預期工作,而不必先創建一個新對象,然後使用Velocity的集合部分對其進行分配。

請記住,可變結構是evil。如果你總是讓你的結構不變,你就不應該陷入這樣的問題。

5

如果Vector2value type,則屬性獲取器將返回一個新副本,並且將Normalize()應用於該副本不會影響原始副本。

換句話說,vt.Velocity不是同一個對象,所以對其中一個進行的更改不反映在另一箇中。

如果Vector2reference type,您將獲得您正在查找的行爲。

0

不知道你的Vector2的具體情況,它聽起來像是一種價值類型。因此,您不會提及您的Velocity,而是其副本。

6

問題涉及到實際性能如何在.NET Framework maneged,但value types如何.NET框架內進行管理。

我曾與CAD仁和,即使它不是從提供的代碼清楚,我Vector2struct(通常它是在快速分配/渲染加速),所以它是一個value type

當你Normalize(...)值類型,你正常化複製它,這就是爲什麼在它的工作原理第二種情況下,導致第一你正常化副本後分配到Ø嚴謹的價值。

希望這會有所幫助。

+0

@AndrasZoltan:它取決於**如何實現** Normalize(..)。我不知道。 – Tigran

+0

根據解釋的行爲,我會**假設** Normalize(..)以某種方式創建Vector2類型的副本。 – Tigran

+0

實際上我回過頭來看 - 當然有一個完全由值類型行爲解釋的微妙之處 - 通過訪問屬性getter,Normalize調用實際上是在數據副本上進行操作,因此永遠不會寫回原始數據;即使Normalize操作回寫到結構自己的數據(我們希望它不會:)) –