C# 为什么更喜欢属性而不是公共变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/737290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why prefer Properties to public variables?
提问by PaulB
Other being able to sanity check values in a setter is there a more underlying reason to prefer properties to public variables?
其他能够对 setter 中的值进行完整性检查是否有更深层次的原因让属性优先于公共变量?
采纳答案by Konrad Rudolph
We've had this subject before but I can't find anything now.
我们以前有过这个主题,但我现在找不到任何东西。
In brief: your needs might change: where there's no sanity check now, one might be required in the future. However, if you change your public fields to properties, this breaks binary compatiblity: every client who uses your code/library would have to re-compile.
简而言之:您的需求可能会发生变化:现在没有健全性检查,将来可能需要。但是,如果您将公共字段更改为属性,则会破坏二进制兼容性:使用您的代码/库的每个客户端都必须重新编译。
This is badbecause it potentially costs a lot of money.
这很糟糕,因为它可能会花费很多钱。
Using properties from the beginning avoids this problem. This even counts for code that is not part of a library. Why? Because you never know: the code (even if highly domain-specific!) might prove useful so you want to refactor it to a library. This refactoring process is obviously made much easier if you are already using properties in place of public/protected fields.
从一开始就使用属性可以避免这个问题。这甚至对于不属于库的代码也很重要。为什么?因为你永远不知道:代码(即使是高度特定于领域的!)可能证明是有用的,所以你想将它重构为一个库。如果您已经在使用属性代替公共/受保护字段,那么这种重构过程显然会变得更加容易。
Additionally, writing public properties is easy in C# 3.0 because you can just use the auto-implemented properties, saving you quite a bit of code:
此外,在 C# 3.0 中编写公共属性很容易,因为您可以只使用自动实现的属性,从而节省了大量代码:
public DataType MyProperty { get; set; }
Will implement the necessary backing field and getter/setter code for you.
将为您实现必要的支持字段和 getter/setter 代码。
I will add a personal note: .NET's behaviour in this regard is somewhat lazy. The compiler could just change public fields to properties on the fly, thus avoiding the problem. VB6 already did this for COM-exposed classes and I see absolutely no reason for VB.NET and C# not to do the same. Perhaps someone on the compiler teams (Jared?) could comment on this.
我将添加一个个人注释:.NET 在这方面的行为有点懒惰。编译器可以动态地将公共字段更改为属性,从而避免这个问题。VB6 已经为 COM 公开的类做了这件事,我认为 VB.NET 和 C# 绝对没有理由不这样做。也许编译器团队中的某个人(Jared?)可以对此发表评论。
回答by Konstantinos
Jeff Atwood has blogged about it:
There are valid reasons to make a trivial property, exactly as depicted above:
- Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
- You can't databind against a variable.
- Changing a variable to a property is a breaking change.
It's a shame there's so much meaningless friction between variables and properties; most of the time they do the exact same thing. Kevin Denteproposed a bit of new syntax that would give us the best of both worlds:
public property int Name;
However, if the distinction between variable and property is such an ongoing problem, I wonder if a more radical solution is in order. Couldn't we ditch variables entirely in favor of properties?Don't properties do exactly the same thing as variables, but with better granular control over visibility?
有充分的理由来创建一个微不足道的财产,正如上面所描述的:
- 反射在变量和属性上的工作方式不同,所以如果你依赖反射,使用所有属性会更容易。
- 您不能对变量进行数据绑定。
- 将变量更改为属性是一项重大更改。
很遗憾,变量和属性之间有这么多无意义的摩擦;大多数时候他们做完全相同的事情。Kevin Dente提出了一些新的语法,可以让我们两全其美:
public property int Name;
然而,如果变量和属性之间的区别是一个持续存在的问题,我想知道是否有更激进的解决方案。我们不能完全抛弃变量而支持属性吗?属性和变量做的事情不是完全一样,但对可见性有更好的粒度控制吗?
回答by Mystic
回答by Mehrdad Afshari
Changing a field to a property in the future is considered a breaking change. Fields are considered implementation details of classes and exposing them publicly breaks encapsulation.
将来将字段更改为属性被视为重大更改。字段被认为是类的实现细节,公开它们会破坏封装。
回答by LeJeune
If you work in a closed environment -- you dont develop a SDK, all classes are used within a same project framework -- there is no difference.
如果您在封闭环境中工作——您不开发 SDK,所有类都在同一个项目框架中使用——没有区别。
The usual argument is that "in the future you may need to do some check on the values, so it is easier with properties". I dont buy it at all.
通常的论点是“将来您可能需要对值进行一些检查,因此使用属性会更容易”。我根本不买。
Using public fields is more readable, less decoration and easier to use.
使用公共字段可读性更高,装饰更少,更易于使用。
回答by Pim Jager
Yes.
是的。
Consider a public varibale which now holds a string, you can simply set it. However, if you decide that that public variable should hold an object which should be initialized with a string then you would have to change all your code using your original object. But if you would have used setter you would only have to change the setter to initialize the object with the provided string.
考虑一个现在包含一个字符串的公共变量,您可以简单地设置它。但是,如果您决定该公共变量应该包含一个应该用字符串初始化的对象,那么您将不得不使用原始对象更改所有代码。但是,如果您使用 setter,则只需更改 setter 即可使用提供的字符串初始化对象。
回答by Carra
You can also protect write access and allow read access with a property:
您还可以使用属性保护写访问并允许读访问:
public int Version { get; private set; }
回答by Sean
In a nutshell:
简而言之:
- You can control acces (readonly,
writeonly, read/write) - You can validate values when setting a property (check for null etc)
- You can do additional processing, such as lazy initialization
- You can change the underlying implementation. For example, a property may be backed by a member variable now, but you can change it to be backed by a DB row without breaking any user code.
- 您可以控制访问(只读、
只写、读/写) - 您可以在设置属性时验证值(检查 null 等)
- 你可以做额外的处理,比如延迟初始化
- 您可以更改底层实现。例如,一个属性现在可能由成员变量支持,但您可以将其更改为由 DB 行支持,而不会破坏任何用户代码。