为什么赢了';没有人接受C#中的公共字段吗?

为什么赢了';没有人接受C#中的公共字段吗?,c#,properties,field,public,C#,Properties,Field,Public,似乎每个C#静态分析器看到公共字段时都想抱怨。但是为什么呢?当然,在某些情况下,一个公共(或内部)字段就足够了,而拥有一个带有get和set方法的属性毫无意义?如果我确信我不会重新定义字段或添加字段(副作用很糟糕,对吧?)-一个简单的字段就足够了吗?因为它破坏了封装-这就是大多数人大量使用访问器的原因。但是,如果您认为它是适合您的任务的正确解决方案,请忽略它(意味着严格的封装投诉),并做适合您的项目的事情。不要让面向对象的纳粹分子告诉你其他的事情。这实际上是关于未来验证你的代码。当你说(强调我的

似乎每个C#静态分析器看到公共字段时都想抱怨。但是为什么呢?当然,在某些情况下,一个公共(或内部)字段就足够了,而拥有一个带有
get
set
方法的属性毫无意义?如果我确信我不会重新定义字段或添加字段(副作用很糟糕,对吧?)-一个简单的字段就足够了吗?

因为它破坏了封装-这就是大多数人大量使用访问器的原因。但是,如果您认为它是适合您的任务的正确解决方案,请忽略它(意味着严格的封装投诉),并做适合您的项目的事情。不要让面向对象的纳粹分子告诉你其他的事情。

这实际上是关于未来验证你的代码。当你说(强调我的):

如果我确信我不会这样做怎么办 正在重新定义字段或添加到 它(副作用很糟糕,对吗?)- 一个简单的字段就足够了吗

这是一个绝对的陈述,正如我们所知(以及大多数静态分析者),生命中只有两个绝对


只是想保护你不受伤害。如果这是一个问题,您应该能够告诉分析器忽略它(通过依赖于您正在使用的分析工具的属性)。

因为稍后更改公共字段以具有get/set访问器将破坏代码。
有关详细信息,请参见。通常,将字段隐藏在属性后面是一个好主意,即使您“确信”不会重新定义字段。很多时候,你今天“肯定知道”的事情明天就会改变。而且,使属性引用字段只是一点小麻烦


也就是说,静态分析器不能代替思维。如果您对自己的设计感到满意,并且根据您的判断,分析器是错误的,那么在这种情况下,请忽略或(如果可能)抑制该警告。

我认为问题的关键在于,通常您不确定以后是否会重新定义该字段或添加到该字段中。封装和隐藏数据的全部意义在于,您可以自由地执行这些操作,而无需更改公共接口并随后破坏依赖类。如果您的属性访问器只是简单的get/set,那么它们将被编译成简单的get/set,因此没有性能问题-鉴于此,您的问题应该是,有什么好的理由不使用它们吗?

鉴于当前的C#3.0允许语法如下的自动属性:

public int Property {get; set;}
在公共字段上使用属性所需的额外工作几乎为零。问题是,您永远无法完全确定字段不会以不同方式使用,或者访问器不会更改,并且考虑到工作中的权衡,没有理由不实现属性


无论如何,分析器抱怨的东西在很大程度上(在本例中,像99.99%的情况)是糟糕的编程实践。。。但无论如何,这只是抱怨。字段可以公开,在某些极端情况下,直接使用字段可能是合理的。一如既往,运用你的常识。。。但是请记住最佳编程实践的基本规则打破惯例真的有很好的理由吗?如果有,那么继续,如果没有,或者如果答案是“它需要更多的工作”,那么坚持实践

属性给表带来的另一个好处是在进行反射时。当您反思您的类时,您可以一次性获得所有属性,而不必获得属性和字段。

而且不要忘记,访问器在处理多个线程时为您提供了灵活性。

嗯,wtf?你是说访问器提供封装吗?这是他们的目标。访问器从外部封装对象的内部工作。因此,如果您有一个透明地在数据库中获取/存储数据的属性,那么这不是封装,仅仅因为它可以从外部访问?我认为您需要重新检查封装的定义……访问器提供了一定程度的间接性。大多数时候你只会看到得到;设置但有时你确实需要隐藏内部细节。如果首先使用访问器,则不必添加大量代码。如果您不这样做,您将不得不这样做,否则某些东西将被破坏。封装并不是隐藏信息。封装是隐藏实现。其思想是,作为对象的客户机,您不想关心其属性是如何存储的,可以通过备份字段、通过访问其他聚合对象、通过直接访问数据库(无论这看起来多么荒谬)来存储它们。属性正好提供了抽象层。它们还允许非常实际的事情,比如验证。我实际上遇到过一个创建公共字段比较方便的情况:为interlocated.Increment公开计数器,它需要一个真正的ref。即使这样,我也可以公开我自己的Increment方法,所以这不是绝对必要的。字段行为与属性不同的另一种情况是结构类型。如果
f
是一个类型为
Rectangle
的字段,并且
p
是同一类型的属性,那么对
thing.f.Width
的访问将只是一个直接整数访问,而读取
thing.p.Width
则需要复制
p
(其中的所有四个字段),然后访问该属性的
Width
字段。在某些情况下,简单字段更好,尤其是在跨应用程序级协议序列化对象的情况下(如XML所述)。说这是“错误的”是一种观点。。。整个Java语言根本没有属性的概念。就我个人而言,我一直在写公共字段,在将百分之一的odball案例重构为属性时,我从未见过它们被破坏。我能想到的唯一一个可能引起问题的情况是,如果你是acce