设置属性不';t设置其内部属性

本文关键字:设置 属性 内部 | 更新日期: 2023-09-27 17:59:32

我最初是从这个地址拿走的: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; }
}

设置属性不';t设置其内部属性

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字段的副本,当修改超出范围时(立即)就会被丢弃。

这是避免像瘟疫这样的可变结构的一个很好的理由。

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

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

检索持有者。属性作为副本并更改副本

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

当您访问holder的属性时,您正在创建原始结构的副本,然后在副本上调用方法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方法时,会创建原始的副本,并且它是由该方法返回的副本,而不是原始