2010-01-28 47 views
3

更新採取以下struct類:自動屬性值不與結構

public struct SingleWraper 
{ 
    private double _myValue; 

    public double MyValue 
    { 
     get { return _myValue; } 
     set { _myValue = value; } 
    } 

    public void SetMyValue(double myValue) 
    { 
     _myValue = myValue; 
    } 
} 

public struct DoubleWraper 
{ 
    public SingleWraper SingWraper { get; set; } 

    public void SetMyValue(double singleVa) 
    { 
     SingWraper.SetMyValue(singleVa); 
    } 
} 

運行以下測試:

[Test] 
    public void SetMyValue() 
    { 
     var singleWraper = new DoubleWraper(); 
     singleWraper.SetMyValue(10); 
     Assert.AreEqual(10,singleWraper.SingWraper.MyValue); 
    } 

它失敗。

但是,如果你DoubleWraper使用自動屬性,即,展開外地如下:

public struct DoubleWraper 
{ 
    private SingleWraper _singWraper; 
    public SingleWraper SingWraper 
    { 
     get { return _singWraper; } 
     set { _singWraper = value; } 
    } 

    public void SetMyValue(double singleVa) 
    { 
     _singWraper.SetMyValue(singleVa); 
    } 
} 

然後測試將通過。

爲什麼這樣呢?

+0

這是一個常見問題。這是本週早些時候的一個答案:http://stackoverflow.com/questions/2132594/chaining-properties-in-c-unexpected-results/2133223#2133223 – 2010-01-28 15:50:18

回答

7

正是在這裏:

_singWraper.SetMyValue(singleVa); 

VS:

SingWraper.SetMyValue(singleVa); 

在第二,你訪問一個財產,所以你克隆結構;基本上這與以下內容相同:

var clonedAndIndependentValue = SingWraper; // getter 
clonedAndIndependentValue.SetMyValue(singleVa); 

注意我們更新了一個不同的結構值;與現場訪問相對照,該訪問與結構值的現有進行對話。

爲什麼可變結構是邪惡的又一個例子。 不要做它。使結構不可變(沒有Set*方法,屬性設置器或其他shenanigans)。或者使用一個班級。

+0

這很可能是可變的危險最明顯的例子之一我在一段時間內看到的結構。 – 2010-01-28 12:42:12

+0

這是一個非常清晰的解釋.. – Graviton 2010-01-28 12:43:18