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

时间:2011-07-25 23:27:56

标签: c# properties

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

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

private Name { get; set; }

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

感谢。

6 个答案:

答案 0 :(得分:6)

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

作为Alan Kay said

  

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

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

因此,对于目前具有琐碎的getter和setter实现的属性使用自动实现的属性非常有用,但可能将来会有更复杂的实现。

答案 1 :(得分:4)

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

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

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

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

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

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

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

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

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

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

int SomeProperty { get; private set; }