2010-01-28 48 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