公有字段与自动属性

我们经常被告知我们应该通过为类字段创buildgetter和setter方法(C#中的属性)来保护封装,而不是将字段暴露给外部世界。

但是有很多时候,一个字段只是在那里保存一个值,并不需要任何计算来获取或设置。 对于这些我们都会做这个数字:

public class Book { private string _title; public string Title { get{ return _title; } set{ _title = value; } } } 

那么,我有一个自白,我不能写所有这些(真的,不必写,不得不看),所以我去stream氓,使用公共领域。

接下来是C#3.0,我看到他们添加了自动属性:

 public class Book { public string Title {get; set;} } 

这是比较整洁的,我很感谢,但是真的,和公共领域有什么不同呢?

 public class Book { public string Title; } 

在前一段相关的问题中 ,Jeff的博客上有一个链接,解释了一些不同之处。

属性与公共variables

  • reflection对variables和属性的作用是不同的,所以如果你依赖reflection,使用所有属性会更容易。
  • 你不能对一个variables进行数据绑定。
  • 将variables更改为属性是一个重大改变。 例如:

     TryGetTitle(out book.Title); // requires a variable 

忽略API问题,我发现最有价值的使用属性是debugging。

CLRdebugging器不支持数据中断点(大多数本机debugging器)。 因此,无法在读取或写入某个类的特定字段时设置中断点。 这在某些debugging场景中是非常有限的。

由于属性是以非常细的方式实现的,因此可以在读取和写入它们的值时设置断点。 这给了他们在田野上的一大步。

只是因为没有人提到它:你不能在接口上定义字段。 所以,如果你必须实现一个定义属性的特定接口,自动属性有时是一个非常好的function。

从一个字段到一个属性的变化会破坏合约(例如要求重新编译所有引用代码)。 所以,当你与其他类别有一个互动点 – 任何公共(而且通常是受保护的)成员,你想要为未来的增长做计划。 总是使用属性来这样做。

今天把它变成一个汽车财产并没有什么意义,而且在3个月的时间里,我们意识到你想让它延迟加载,并且在getter中放置一个空的支票。 如果你使用过一个字段,这是一个重新编译的变化,最坏的情况是不可能的,这取决于谁是你的程序集的依赖者。

一个常常被忽视的巨大差异并没有在其他答案中提及: 重写 。 您可以声明虚拟属性并覆盖它们,而对于公共成员字段则不能这样做。

与公有字段相比,自动实现的属性的另一个优点是可以使集合访问器为私有或受保护的,从而提供了比公有字段更好地控制的对象类。

这完全是关于版本控制和API稳定性的。 在版本1中没有区别,但是如果您决定在版本2中使用某种types的错误检查来确定属性,则不必更改API,也不需要更改任何代码财产的定义。

public领域是没有错的。 但是记住创buildprivate字段的getter/setter是没有封装的。 海事组织,如果你不关心Property其他function,你也可以public

如果您稍后决定通过比较集合或数据库来检查标题是否是唯一的,则可以在属性中执行此操作,而不更改依赖于该代码的任何代码。

如果你只是公开的属性,那么你会有更less的灵活性。

在不违反契约的情况下,额外的灵活性对于我来说最重要的是使用属性,直到我真正需要灵活性,自动生成才是最有意义的。

有一件事我觉得非常有用,以及所有的代码和testing的原因是,如果它是一个属性与字段是Visual Studio IDE显示您的属性,而不是字段的引用。

一方面也是performance。 我发现有趣的事情 – 在debugging版本的访问属性是几乎加倍 (如果不是更多)比字段,但在发布版本访问属性是比边缘快一点!