为什么在C#中使用简单的属性而不是字段?

可能重复:
我应该使用公共财产和私人领域或公共领域的数据?
自动属性和C#3.0中的公共字段的区别

人们似乎在教条上坚持使用公共财产,而为什么在简单财产的情况下,它是如此地极其重要?

怎么

public int Foo { get; set; } 

如此令人难以置信的不同

 public int Foo; 

在我的头顶,我可以想到两者之间的实际差异:

  • 使用reflection访问成员(罕见的,最体面的reflectionalgorithm将考虑到差异)
  • 第二个条目允许您使用该字段作为ref和out参数的有效参数,这似乎是使用字段版本的优势
  • 字段不能在远程处理(可能,我从来没有使用远程处理,但我想他们不会)?

除了这些相当罕见的情况之外,将Foo更改为计算属性稍后会导致更改0行代码。

使用属性有几个明显的优点:

  • 它允许版本化,如果以后你需要额外的逻辑。 向getter或setter添加逻辑不会破坏现有的代码。
  • 它允许数据绑定正常工作(大多数数据绑定框架不适用于字段)。

另外,几乎没有缺点。 像这样的简单,自动的属性由JIT编译器内联,所以没有理由不使用它们。

另外,你提到:

除了这些相当罕见的情况之外,将Foo更改为计算属性稍后会导致更改0行代码。

这并不要求你的代码被改变,但它确实会迫使你重新编译你所有的代码。 从字段更改为属性是一个突变的API更改,这将需要任何引用您的程序集的程序集重新编译。 通过将其设置为自动属性,您可以发布新的二进制文件,并保持API兼容性。 这是我上面提到的“版本控制”优势…

一个很好的理由是你可以改变get / set的可访问性。

 public int Foo {get; protected set;} 

属性是逻辑上代表由该类build模的事物的属性的语言元素。 class车模拟汽车; 颜色是汽车的财产; 因此,Color是Car的一个属性。

字段是表示类的实现细节的语言元素。 你的车没有“色域”,所以你的程序的汽车表示不应该暴露一个叫做颜色的字段。 它可能包含一个私有的实现细节,其中Color属性是由一个字段实现的,但这是一个私有的实现细节,而不是该模型的可公开访问的部分。

主要是因为惯例。

其中一个可靠的论点是,如果您以后需要从一个字段更改为一个属性,那么引用您的所有程序集都需要重新编译。

reflection确实偶尔会出现,但很less。 一些序列化types基于属性。

您可以使属性变为虚拟,并在派生类中重写它们的实现。 这是很多将你的对象包装在生成的代理类中的库中的一个重要因素,例如NHibernate实现延迟加载的方式。 这是不可能的字段。