C#auto property vs normal fields

时间:2013-03-21 14:57:48

标签: 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();
    }
}

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; 
            }
    }
}

旧代码不会被破坏。

5 个答案:

答案 0 :(得分:8)

  

AFAIK他们的行为完全相同。

不,他们不会。

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

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

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

有关更多咆哮,请参阅我的article on this

答案 1 :(得分:1)

Foo.Something是一个字段,Bar.Something是一个自动实现的属性。这是一个巨大的差异。

您可以像访问字段一样访问属性,但在访问属性时会在内部调用set / get方法。

因此,当您说myBar.Something = "asdf"时,C#编译器会将其转换为对setter方法的调用:myBar.set_Something("asdf")。将自动为您生成setter和getter方法,以及实际值的支持字段。

通过使用get和set方法将Foo.Something更改为属性,您将破坏二进制兼容性,这意味着当它仍然是字段时,您将不得不重新编译使用Foo.Something的所有程序集。

答案 2 :(得分:0)

属性的getter和setter(包括自动的)具有方法调用成本。应该避免使用公共字段,以便通过访问保持干净。

答案 3 :(得分:0)

1)您可以添加私人访问者来获取或设置和控制对财产的访问权。

public object MyProp {get; private set;}

你可以在任何地方阅读道具,但只能在课堂内写作

2)您可以将某些逻辑连接到读/写属性。如果是现场你不能做任何额外的事情

3)您无法序列化字段

答案 4 :(得分:0)

public string Something{get; set;}只是语法糖;编译器实际上将其扩展为方法。因此,只要为了它而将所有get; set;字段放在所有地方是没有意义的。