Properties vs Public member variables
Possible Duplicate:
What is the difference between a field and a property in C#
我是一个初学者,我已经阅读了所有关于类属性的内容。Books声明属性允许您间接访问成员变量。好吧,那么它与公开和直接访问字段有什么不同呢?
以下是Jesse Liberty学习C 3.0的引言:
For example, you might want external
classes to be able to read a value, but not change it; or you might want to write
some code so that the internal field can accept only values in a certain range. If you
grant external classes free access to your member fields, you can’t control any of that.
我不明白他在说什么。有人能进一步解释这一点吗,或者举例说明我为什么要使用某个属性而不公开该字段。正如我现在所理解的,他们都会完成同样的事情……所以我显然错过了一些东西。
到目前为止提供的其他答案提供了访问器/转换器逻辑优势的详细信息,但似乎都遗漏了关于对象封装的思想要点。
你看,类成员字段是一个实现细节。例如,如果有一个表示集合的类,那么可以将其实现为链接列表(并通过公共字段公开根节点),或者将其实现为可调整大小的数组并公开index0成员。
揭示实现细节的问题是,您会丢失类与其使用者之间任何类型的定义接口。通过确保所有操作都是通过定义的方法(由类本身控制)完成的,您可以更容易地使用和提供长期的观点。例如,您可以更容易地将集合实现从一种类型(链接列表)转换为另一种类型(数组),而不会破坏与类的消费者的任何契约。
不要担心琐碎的访问器/转换器方法对性能的影响:JIT编译器将内联属性方法。如果运行一些基准测试,您将看到属性与字段的性能是相同的。
他说属性可以提供getter,但不能提供setter,因此使它们成为只读的(例如)
属性只是一种方法的句法糖,例如
1 | public int SomeProperty { get; set; } |
只是糖
1 2 3 4 5 6 7 8 9 10 11 | private int _someProperty; public int SomeProperty_get() { return _someProperty; } public void SomeProperty_set(int value) { _someProperty = value; } |
这意味着属性设置器/getter可以应用仅公共字段不能应用的逻辑
编辑:我不确定clr为自动属性提供了哪些字段名-这只是一个例子:)
编辑2:
只读属性的示例:
1 | public int SomeProperty { get; } |
最后是一个公共的读-私有的写(用于自动属性)
1 | public int SomeProperty { get; private set; } |
当您不必费心在中键入支持字段时非常有用:)
请记住,如果您希望将逻辑应用于成员,那么属性就是可行的方法。这是许多框架的工作方式(例如,通过使用属性来跟踪"脏"对象,以告诉某种对象管理器某些内容已更改,使用公共字段是不可能的)
属性可能有副作用,它们围绕"getter"和"setter"方法提供了语法上的优势。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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具有不同的保护级别,不能对字段进行保护。
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } } |
"属性"和"成员访问"之间有许多重要的区别。
最重要的是,您可以通过属性使成员成为只读的(您可以访问状态,但不能更改它)。就像Java中的"GETTER()"和"SETTER()"方法一样。
还可以从属性返回计算值(生成一个"即时"的值,就像它是一个变量一样)。
属性可以配置为:
它们是只读的,
它们只写
它们可以被外部对象读取,但只能由类的内部设置
公营企业
正如其他人发布的那样,您也可以将逻辑放入getter和setter中。例如,在允许属性下注设置为新值之前,可以检查该值是否可接受。
对于公共字段,您不能这样做。
基本上,公共领域是你能拥有的最愚蠢的财产。鉴于.NET现在允许为您的属性自动打包字段。再也没有充分的理由使用公共领域了。
如果你有EDOCX1[0]我可以把它设为-200或20000,你对此无能为力。
例如,如果使用属性,可以检查年龄是否在0到150之间。
编辑:根据伊恩诺顿的例子(伙计,那太快了)