我应该使用公共财产和私人领域或公共领域的数据?
在我看到的大部分代码中(在SO上,codeproject.com和我倾向于在我自己的代码中这样做),我已经看到公共属性是为类中包含的每个专用字段创build的,即使它们是最get; set;
基本typesget; set;
get; set;
喜欢:
private int myInt; public int MyInt { get { return myInt; } set { myInt = value } }
我的问题是:这与以下不同:
public int MyInt;
如果我们应该使用属性,而不是公共领域,为什么我们应该在这个特定的情况下使用它们? (我不是在讨论更复杂的例子,在这些例子中,getter和setter实际上做了一些特殊的事情,或者只有一个get或set(只读/写)而不是返回/设置一个私有字段的值。 它似乎没有添加任何额外的封装,只有在智能感知中提供一个很好的图标,并放置在类图的特殊部分!
看到这篇文章http://blog.codinghorror.com/properties-vs-public-variables/
特别
- reflection对variables和属性的作用是不同的,所以如果你依赖reflection,使用所有属性会更容易。
- 你不能对一个variables进行数据绑定。
- 将variables更改为属性是一个重大改变。
三个原因:
- 你不能像属性一样覆盖子类中的字段。
- 你最终可能需要一个更复杂的getter或setter,但是如果它是一个字段,改变它会破坏API。
- 惯例。 就是这样做的。
我相信还有更多的原因,我只是没有想到。
在.Net 3.x中,你可以使用像这样的自动属性:
public int Age { get; set; }
而不是老学校的方式,你自己的私人领域是这样的:
private int age; public int Age { get { return age; } set { age = value; } }
这使得它像创build一个字段一样简单,但没有突破性的变化问题(等等)。
当你创build私有字段名称和一个简单的公共属性名称 ,实际上获取并设置名称字段值
public string Name { get { return name; } }
而且你在你的类外的任何地方使用这个属性,有一天你决定这个类的Name属性实际上是指lastName字段(或者你想返回一个string“My name:”+ name),你只需要改变代码里面的属性:
public string Name { get { return lastName; //return "My name: "+name; } }
如果您在外部代码中的任何地方都使用公用字段名称 ,那么在您使用它的任何地方都必须将名称更改为lastName 。
那么它确实有所作为。 公共数据可以在对象实例不知道的情况下进行更改。 使用getter和setter对象总是知道已经做出了改变。
请记住,封装数据只是朝着更好的结构化devise迈出的第一步,它本身不是最终目标。
在以下情况下您必须使用属性:
- 当您需要将属性中的数据序列化为某种格式时。
- 当您需要覆盖派生类中的属性时。
- 当你用一些逻辑来实现get和set方法。 例如,当你实现Singleton模式。
- 当你从接口派生出来的时候,声明属性。
- 当你有与思考有关的具体问题。
这取决于?
我总是使用getters&setters,因为他们创build了这个快捷方式:
public int Foo {get; 组; }
在编译时它被翻译。 现在你不能想象它,但是它在那里,如果你想要看起来,你可以稍后再拼出来。
然而,公共的,私人的,受保护的……这些都是你想要调整数据的问题。 我们大量使用inheritance,这对我们来说是一个非常普遍的方法,所以只有孩子才能编辑某些属性。
protected _foo; public Foo { get { return _foo; } } //lack of set intentional.
原因有很多。
主要是:
- variables设置后,您可以执行其他一些function
- 你可以防止设置和提供只得到
- 有些“东西”只适用于属性(比如DataBinding)
- 您可以隐藏该属性的实现[也许这是一个ViewStatevariables,在ASP.NET中)。
重点是 – 如果更进一步,你想确保每次myInt
引用什么特别的事情发生(一个日志文件被写入,它被改为42等)? 如果没有获得者和制定者,你就无法做到这一点。 有时候编制你可能需要的东西是明智的,而不是你现在需要的东西。
实际上,如果你使用的是Silverlight,你会意识到这些字段不能被设置为一个静态资源,因此你将不得不使用一个属性(甚至访问一个const
)。
我已经意识到,当我试图联合在复合制导(PRISM)中使用的地区名称。
然而,这只是一个语言限制,除了static
/ const
字段,我也使用属性。
这个想法是你不应该无意间/无意中改变一个class级私人领域的价值。 当你使用get和set时,这意味着你有意和有意地改变了类私有域。
将值设置为专用字段只会改变该字段,但是在属性中可以处理另一个参数,例如,可以在设置值之后调用方法
私人string_email; 公共string { 得到 { 返回this._email; } 组 { this._email = value; ReplaceList(); // ** } }
我不能相信有11个答案,没有人这样说过:
并不是所有的私人领域都应该作为公共财产。 你当然应该使用任何非私人的属性,但是你应该尽可能多地保持你的私人空间。