属性vs公共成员变量

可能重复:
C#中的字段和属性有什么区别?

我是一个初学程序员,我已经阅读了所有关于类属性的内容。 书籍声明属性允许您间接访问成员变量。 那么,是什么让它与公共领域直接访问并直接访问它有何不同?

以下是Jesse Liberty学习C#3.0的引用:

例如,您可能希望外部类能够读取值,但不能更改它; 或者您可能想要编写一些代码,以便内部字段只能接受某个范围内的值。 如果您授予外部类免费访问您的成员字段,则无法控制其中任何一个。

我不明白他在这说什么。 有人可以进一步解释这一点,或举例说明为什么我要使用财产而不是公开该字段。 据我所知,现在他们都会完成同样的事情……所以我显然在这里遗漏了一些东西。

属性可能有副作用,它们围绕’getter’和’setter’方法提供语法糖。

public class MyClass { int sizeValue = 0; public int Size { get { return sizeValue; } set { if ( value < 10 ) throw new Exception("Size too small"); sizeValue = value; } } } 

属性也可以为get和set提供不同级别的保护,您不能对字段执行此操作。

 public class MyOtherClass { // only this object can set this. public int Level { get; private set; } // only things in the same assembly can set this. public string Name { get; internal set; } } 

他说属性可以提供一个getter而不是setter,因此将它们设置为只读(例如)

属性只是方法的语法糖,例如

 public int SomeProperty { get; set; } 

只是糖

 private int _someProperty; public int SomeProperty_get() { return _someProperty; } public void SomeProperty_set(int value) { _someProperty = value; } 

这意味着属性设置者/获取者可以应用仅仅公共领域不能的逻辑

编辑:我不确定CLR为自动属性提供支持字段的字段名称 – 这只是一个例子:)

EDIT2:

只读属性的示例:

 public int SomeProperty { get; } 

最后是公开阅读 – 私人写作(针对autoproperties)

 public int SomeProperty { get; private set; } 

当你不能打扰在:)中输入支持字段时真的很有用

请记住,如果您希望将逻辑应用于成员,则可以使用属性。 这是许多框架工作的方式(例如,通过使用属性来告诉某种对象管理器某些事情发生了变化来跟踪’脏’对象,使用公共字段是不可能的)

到目前为止提供的其他答案提供了访问器/ mutator逻辑的优点的详细信息,但似乎都错过了关于对象封装的意识形态观点。

你看,类成员字段是一个实现细节。 例如,如果您有一个表示集合的类,那么您可以将其实现为链接列表(并通过公共字段公开根节点),或者您可以将其实现为可resize的数组并公开index0成员。

揭示实现细节的问题在于您丢失了类与其使用者之间的任何类型的已定义接口。 通过确保所有操作都通过定义的方法(由类本身控制)完成,您可以更轻松地使用并提供长期观点。 例如,您可以更轻松地将集合实现从一种类型(链接列表)转换为另一种类型(数组),而不会破坏与您的类“消费者”的任何合同。

不要担心琐碎的访问器/ mutator方法对性能的影响:JIT编译器将内联属性方法。 如果你运行一些基准测试,你会发现属性与字段的性能是相同的。

“属性”和“成员访问”之间存在许多重要差异。

最重要的是,您可以通过属性将成员设为只读(您可以访问状态,但不能更改它)。 就像Java中的“getter()”和“setter()”方法一样。

您还可以从属性返回计算值(生成“即时”值,就好像它是一个变量)。

可以配置属性,以便:

它们是只读的, Public MyProp {get;}

它们是只写的Public MyProp {set;}

它们可由外部对象读取,但只能由类的内部设置

Public MyProp {get; private set;} MyProp {get; private set;}

正如其他人发布的那样,你也可以将逻辑放入你的getter和setter中。 例如,在允许属性下注设置为新值之前,您可以检查该值是否可接受。

你不能用公共领域做任何事情。

基本上,公共领域是你可以拥有的最愚蠢的财产。 鉴于.Net现在允许为您的属性自动填充字段。 没有充分的理由再使用公共领域了。

如果你有Public Int MyAge我可以将它设置为-200或20,000,你无能为力。

例如,如果您使用属性,则可以检查年龄是否在0到150之间。

编辑:根据IanNorton的例子(男人,那很快)