为什么C#自动实现的属性是公开的?

在我看到的所有示例中,即使在MSDN文档示例中,C#自动实现的属性也是公开的。 来自C ++背景,我一直被告知,将成员数据设为私有是个好主意,除非有充分的理由不这样做。

为什么以下从未使用过(至少我从未见过它):

private Name { get; set; } 

我查看了MSDN文档并阅读了几个关于自动实现属性的教程,但似乎没有任何关于它们的优缺点的建议以及何时应该避免它们。 自动实现的属性会破坏程序安全性吗? 是否有应避免的情况? 在哪些情况下他们是理想的选择?

谢谢。

你是正确的,只是公开支持字段的自动实现的属性对公共字段没有太大的好处。

正如Alan Kay所说 :

但是大多数使用setter的人只是使用它们来模拟内部变量的直接赋值, 这违反了真实OOP的精神和意图

但是,公共字段上的自动实现的属性有一个优点,那就是以后修改实现是一个不间断的更改。 如果您有一个公共字段,并且您的类外部的代码操作该公共字段,则无法将其更改为该类的未来版本中的私有字段,否则将不得不重新编译接触该字段的任何其他代码。 相比之下,一旦拥有了公共属性,就可以在将来的版本中修改该属性的实现,并且客户端类可以继续使用它而不做任何更改。

因此,对于现在具有普通的getter和setter实现的属性使用自动实现的属性是有用的,但是将来可能会有更复杂的实现。

你有没有问过自己为什么总是被教导让成员私密化是个好主意?

这是因为(除其他原因外) 字段是实现细节 。 “将数据存储在存储器中”的细节,对于希望检索或设置数据的任何对象来说,这是一个不重要的细节。 另一个类不需要关心他是否可以访问某个内存插槽 – 他只是想要一个可以传递或检索值的接口 – 有getter和setter,或者属性。

将该属性与“基于存储器的存储”的细节分离后,我们获得了许多优势。 主要是 – 我们可以覆盖获取和设置的行为,而不会破坏使用该属性的任何代码。 我们还可以使用该属性作为抽象,以通过许多不同的实现来检索数据。 这对于测试/模拟行为以及提供替代存储非常有用。 如果其他类依赖于“内存存储”的实现细节,那么在不破坏所有类的情况下,您将无法更改类的行为。

在自动属性出现之前,我们通常会存储一个字段并创建一个getter和setter来封装它,原因如上所述。 汽车属性为我们自动化。 我们可能会编写通常在代码中使用字段的代码,但是我们这样做仍然坚持“我现在将这个作为一个字段,但如果标准发生变化,可能会在以后更改”。

由于一个类知道它自己的实现,因此创建私有自动属性通常是毫无意义的努力,你不会隐藏已知的细节。 如果需要公开子类,受保护的自动属性可能很有用。

至于应该避免的情况:当你想要只读数据时。 (构造对象后不会改变的数据)。 自动属性缺少允许您创建由只读数据支持的自动属性的语法。

自动实现的属性具有私有后备成员。 编译器会为您添加它们。 它只是一个捷径

 private int _aMember; public int AMember { get {return _aMember;} set {_aMember = value;} } 

你使用它们你在getter / setter中没有真正的逻辑(除了需要封装)。

自动实现的属性只是常见模式的快捷方式。 每当你在C ++中拥有一个具有相应get和set函数的私有成员时,你就可以用C#中的auto属性完成同样的事情。 它们不会引入任何不同的最佳实践或安全问题。

具有公共getter和setter的自动实现的属性是具有普通get和set实现的私有后备字段的快捷方式。

您应该将它们视为类似于使用C ++中的公共get和set方法的私有字段。 这是C#上属性的一个角色。

属性不是“成员”数据。 他们是你的一种

 const T& field() const; T& field(); 

事物的类型,或获取和设置方法,即它们是访问者。

如果您不需要暴露成员,请不要在属性中表达它们。 在自动生成的情况下,您可以简单地(从C#2.0 afaik开始)写入

 int SomeProperty { get; private set; }