C#3.0的自动属性 ​​- 有用或没有?

注意:这是我刚刚开始C#时发布的。 随着2014年的知识,我可以真正地说,自动属性是曾经发生在C#语言的最好的事情之一。

我习惯于在C#中使用私有和公共字段来创build我的属性:

private string title; public string Title { get { return title; } set { title = value; } } 

现在,在.NET 3.0中,我们获得了自动属性:

 public string Title { get; set; } 

我知道这是更多的哲学/主观的问题,但是有没有任何理由使用这些自动属性,除了保存每行的代码5行? 我个人的抱怨是这些属性隐藏了我的东西,我不是一个黑魔法的粉丝。

事实上,隐藏的专用字段甚至不会显示在debugging器中,这是可以的,因为get / set函数什么也不做。 但是当我想实际实现一些getter / setter逻辑时,我必须使用私有/公共对。

我看到了保存大量代码(一对六行)而不会丢失后来改变getter / setter逻辑的好处,但是我可以通过简单地声明一个公共字段“公共string标题” {get; 组; }块,从而甚至节省更多的代码。

那么,我在这里错过了什么? 为什么会有人想要使用自动属性?

我们一直在堆栈溢出中使用它们。

您也可能对“ 属性与公共variables”的讨论感兴趣。 恕我直言,这是真正的这是一个反应,为此,这是伟大的。

是的,它只是保存代码。 当你有很多东西的时候,阅读更容易。 他们写得更快,更容易维护。 保存代码总是一个好的目标。

你可以设置不同的范围:

 public string PropertyName { get; private set; } 

所以只能在课堂内改变属性。 这并不是真正的不变的,因为你仍然可以通过reflection来访问私有setter。

从C#6开始,您还可以创build真正的readonly属性 – 即不能在构造函数之外更改的不可变属性:

 public string PropertyName { get; } public MyClass() { this.PropertyName = "whatever"; } 

在编译时将会变成:

 readonly string pName; public string PropertyName { get { return this.pName; } } public MyClass() { this.pName = "whatever"; } 

在有很多成员的不可变类中,这节省了大量的额外代码。

使用字段而不是属性的三大缺点是:

  1. 你不能绑定到一个字段,而你可以到一个属性
  2. 如果你开始使用一个字段,你不能以后(很容易)把它们改成一个属性
  3. 有一些属性可以添加到不能添加到字段的属性中

我个人喜欢汽车性能。 保存代码行有什么问题? 如果你想在getter或setter中做东西,那么稍后将它们转换为普通属性是没有问题的。

正如你所说,你可以使用字段,如果你想添加逻辑给后者,你可以将它们转换成属性。 但是,这可能会导致任何使用reflection(也可能在其他地方)的问题。

此外,这些属性允许您为getter和setter设置不同的访问级别,这是您无法使用字段的。

我想这跟var关键字一样。 个人喜好的问题。

来自C ++创build者Bjarne Stroustrup:

我特别不喜欢有很多get和set函数的类。 这往往表明它本来不应该是一个阶级。 这只是一个数据结构。 如果它确实是一个数据结构,那么把它变成一个数据结构。

你知道吗? 他是对的。 多久你只是简单地将私有字段包装在一个get和set中,而没有在get / set中做任何事情,只是因为它是“面向对象”的事情。 这是微软解决这个问题的方法; 他们基本上是公共领域,你可以绑定到。

有一件事似乎没有人提到过,自动属性对于不可变的对象(通常是不可变的结构)来说是不可用的。 因为你真的应该这样做:

 private readonly string title; public string Title { get { return this.title; } } 

(通过传递的参数在构造函数中初始化该字段,然后是只读的。)

所以这比简单的get / private set有优势。

我总是创build属性而不是公共字段,因为您可以在接口定义中使用属性,所以不能在接口定义中使用公共字段。

自动属性和C#中的其他任何东西一样都是黑魔法。 一旦你把它编译到IL而不是它被扩展到一个正常的C#属性,它比许多其他的语言结构less得多的黑魔法。

我一直使用自动属性。 在C#3之前,我不能打扰所有的input,只是使用公共variables。

我唯一想念的是能够做到这一点:

 public string Name = "DefaultName"; 

您必须将默认值转换为具有属性的构造函数。 单调乏味:-(

我认为任何直观和减less代码行的构造是一个很大的优点。

这些function使得像Ruby这样的语言function非常强大(即dynamicfunction,这也有助于减less多余的代码)。

Ruby始终如此:

 attr_accessor :my_property attr_reader :my_getter attr_writer :my_setter 

我与他们唯一的问题是,他们不够远。 在编译器的同一版本中添加了自动属性,添加了部分方法。 为什么他们不把这两个放在一起超出了我。 一个简单的“部分On <PropertyName>改变”将使这些事情真的非常有用。

这很简单,它很短,如果你想在属性的主体内部创build一个真正的实现,它不会破坏你的types的外部接口。

就如此容易。

这里要注意的一点是,就我的理解,这只是 C#3.0端的语法糖,意味着编译器生成的IL是相同的。 我同意避免黑魔法,但同样的道理,同样的事情通常是一件好事。

在我看来,你应该总是使用自动属性,而不是公共领域。 这就是说,这是一个妥协:

从内部字段开始,使用用于属性的命名约定。 当你第一次

  • 需要从组件外部进入现场,或者
  • 需要将逻辑连接到getter / setter

做这个:

  1. 重命名该字段
  2. 使其私密
  3. 添加公共财产

你的客户端代码不需要改变。

但是,有一天,你的系统会增长,你会分解成单独的程序集和多个解决scheme。 当这种情况发生时,任何暴露的领域都会回来困扰你,因为正如杰夫所说, 将公共领域改为公共财产是一个突破API的变化 。

我使用CodeRush,它比自动属性更快。

去做这个:

  private string title; public string Title { get { return title; } set { title = value; } } 

总共需要八个击键。

那么与代码片段相同名称的自动属性将是总共七个按键;)

@Domenic:我不明白..你不能用自动属性来做这个吗?

 public string Title { get; } 

要么

 public string Title { get; private set; } 

这是你所说的吗?

我对自动属性最大的抱怨是,他们的目的是为了节省时间,但我经常发现我不得不在晚些时候将它们扩展成全面的属性。

什么VS2008是缺less爆炸自动属性重构。

我们有一个封装字段重构的事实,使我更快地使用公共字段的方式。