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

Rob*_*vis 29 c#

可能重复:
我应该使用公共属性和私有字段或公共字段来获取数据吗?
C#3.0中自动属性和公共字段之间的区别

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

怎么

public int Foo { get; set; }
Run Code Online (Sandbox Code Playgroud)

非常不同于

public int Foo;
Run Code Online (Sandbox Code Playgroud)

在我的脑海中,我可以想到两者之间的实际差异:

  • 使用反射访问成员(罕见,最体面的反射算法将解释差异)
  • 第二个条目允许您使用该字段作为ref和out参数的有效参数,这似乎是使用字段版本的一个优势
  • 字段在Remoting中不起作用(可能,我从未使用过远程处理,但我想他们不会)

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

Ree*_*sey 61

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

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

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

另外,你提到:

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

这不需要更改代码,但它会强制您重新编译所有代码.从字段更改为属性是一个重大的API更改,这将需要重新编译引用程序集的任何程序集.通过使其成为自动属性,您可以发布新的二进制文件,并保持API兼容性.这是我上面提到的"版本化"优势......

  • 我倾向于同意,您可能不想使用属性的唯一原因是处理“ref”或“out”要求,尽管您可以轻松地生成要使用的临时变量,然后将属性设置为将被处置的变量不久。 (2认同)

Joh*_*nan 44

一个很好的理由是你可以改变获取/设置的可访问性.

public int Foo {get; protected set;}
Run Code Online (Sandbox Code Playgroud)

  • 哇,我实际上没有意识到这一点。+1 谢谢 (2认同)

Eri*_*ert 26

属性是一种语言元素,它在逻辑上表示由类建模的事物的属性.汽车模型车; 颜色是汽车的财产; 因此,颜色是汽车的属性.

字段是表示类的实现细节的语言元素.您的汽车没有"颜色区域",因此您的程序代表汽车不应该暴露一个名为Color的字段.它可能包含私有实现细节,其中属性Color由字段实现,但这是私有实现细节,而不是模型的公共可访问部分.

  • @ v.oddou:几乎语言的每个特征都是多余的.例如,方法是不必要的; 方法可以只是用lambdas初始化的委托类型的字段.冗余通常被认为是一件坏事,但根本不是; 冗余使事情更容易理解.正如我在答案中所指出的,有两个特性,属性和字段,让我们巧妙地向读者传达成员是否具有语义重要性或仅仅是该类型的机制. (7认同)
  • @Eric:如果字段是一个实现细节,为什么我们可以将其公开? (2认同)
  • @Karol:嗯,有优点也有缺点。例如:C# 必须能够与其他 .NET 语言良好地互操作,并且必须为 Java 和 C++ 用户所熟悉。在某些情况下,出于性能原因,您希望直接访问结构体的字段,特别是对于用于与 C++ 互操作的普通旧数据结构。并且您不能通过引用传递属性。所以并不是说它们的用例为零。但请注意,我命名的所有用例都暗示字段是机制。 (2认同)

Dav*_*gue 6

主要是因为惯例.

它的一个坚实的论点是,如果您以后需要从字段更改为属性,则需要重新编译引用您的所有程序集.

反思确实偶尔进入,但很少.某些序列化类型基于属性.


Jon*_*noW 6

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


归档时间:

查看次数:

21268 次

最近记录:

15 年,6 月 前