C#autoproperty与普通字段

ade*_*kcz 3 c# automatic-properties

在这个例子中,Foo.Something和Bar.Something之间有什么有效的区别吗?

class Foo
{
    public string Something;
}

class Bar
{
    public string Something{get; set;}
}

class Program
{
    static void Main(string[] args)
    {
        var MyFoo = new Foo();
        MyFoo.Something = "Hello: foo";
        System.Console.WriteLine(MyFoo.Something);

        var MyBar = new Bar();
        MyBar.Something = "Hello: bar";
        System.Console.WriteLine(MyBar.Something);
        System.Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

AFAIK他们的行为完全相同.如果他们为什么不在Foo中使用普通的字段?在java中,我们使用setter来强制执行新的不变量而不会破坏代码和getter来返回安全数据但是在c#中你总是可以将Foo重写为:

class Foo
{
    private string _Something;
    public string Something
    {
        get { 
            //logic
            return _Something; 
            }
        set { 
            //check new invariant
            _Something = value; 
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

旧代码不会被破坏.

Jon*_*eet 8

AFAIK他们的行为完全相同.

不,他们没有.

  • 字段不能用于数据绑定(至少在某些绑定实现中)
  • 您可以稍后为属性添加更多逻辑,而不会破坏源或二进制兼容性
  • 属性不能通过引用传递
  • 您无法将初始化程序添加到自动实现的属性中
  • 它们在反射方面明显不同
  • 从哲学上讲,属性在逻辑上是API的一部分,而字段是实现细节

在c#中,您总是可以将Foo重写为:[...]

如果你不关心二进制或源兼容性,那么你可以.在某些情况下,这确实不是问题 - 在其他情况下,这是一个非常非常严重的问题.为什么不从一开始就选择公开您的API而不是您的实施细节?这并不像添加{ get; set; }你的代码就会增加更多的混乱......

有关更多咆哮,请参阅我的文章.