设置属性不设置其内部属性

时间:2014-04-23 05:00:51

标签: c#

我最初是从这个地址接过来的:http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx因为某些原因我无法理解它。有人可以解释一下为什么Console.WriteLine(holder.Property.Value);输出0。

void Main()
{
    MutableStructHolder holder = new MutableStructHolder();
    holder.Field.SetValue(10);
    holder.Property.SetValue(10);
    Console.WriteLine(holder.Field.Value); // Outputs 10
    Console.WriteLine(holder.Property.Value); // Outputs 0
}

struct MutableStruct
{
    public int Value { get; set; }

    public void SetValue(int newValue)
    {
        Value = newValue;
    }
}

class MutableStructHolder
{
    public MutableStruct Field;
    public MutableStruct Property { get; set; }
}

4 个答案:

答案 0 :(得分:4)

class MutableStructHolder
{
    public MutableStruct Field;
    public MutableStruct Property { get; set; }
}

相当于

class MutableStructHolder
{
    public MutableStruct Field;

    private MutableStruct _Property;
    public MutableStruct Property { 
       get { return _Property; }
       set { _Property = value; }
    }
}

相当于:

class MutableStructHolder
{
    public MutableStruct Field;

    private MutableStruct _Property;
    public MutableStruct getProperty() { 
       return _Property;
    }
    public void setProperty(MutableStruct value) { 
       _Property = value;
    }
}

所以,当你这样做时:

holder.Property.SetValue(10);

你实际上是这样做的:

holder.getProperty().SetValue(10);

相当于:

MutableStruct temp = holder.getProperty(); 
temp.SetValue(10);

因为结构是值类型,temp实际上是底层_Property字段的副本,当你的修改超出范围时你的修改就被丢弃了)。

avoid mutable structs like the plague这是一个很好的理由。

答案 1 :(得分:1)

这是因为结构是值类型,当你传递它时会创建一个副本。使用字段,您将访问结构的真实版本,而对于属性,它将返回它的副本。然后,您可以更改此副本,然后将该副本丢弃。

答案 2 :(得分:1)

链接代码中的注释解释了这一点......

  

将holder.Property作为副本检索并更改副本

换句话说,.SetValue(10)上的holder.Property适用于holder.Property副本,而非holder.Property本身。

答案 3 :(得分:1)

当您访问持有者的属性时,您正在创建原始结构的副本,然后在副本上调用方法SetValue

以下代码在功能上会做同样的

//First create a copy of the original
var property = new MutableStruct();
property.Value = holder.Property.Value;
//That's not how the copy is actually created but the result is the same

//set the value on the copy
property.SetValue(10);

//print the value of the original
Console.WriteLine(holder.Property.Value);

属性会发生这种情况,因为属性本​​质上是方法。当您调用get方法时,会创建原始文件的副本,并且该方法返回的副本不是原始文件