(C#)属性(property)
属性是字段和方法的一个交集。看起来像是一个字段,行为上又像是一个方法。
是类维持了封装性,有可以方便地使用字段。
- 访问属性的语法和访问一个字段(类成员)的语法是相同的。(
- 实际上,编译器自动转换为对特定accessor方法(取值和赋值方法统称为accessor方法)的调用
属性的声明如下:
- AccessModifier Type PropertyName
- {
- get
- {
- //取值代码 (get accessor )
- }
- set
- {
- //赋值代码 (set accessor )
- }
- }
举例如下:配置ScreenPosition 的属性.
- struct ScreenPosition
- {
- //小写的x,y是私有字段
- private int x, y;
- public ScreenPosition(int X, int Y)
- {
- this.x = rangeCheckedX(X);
- this.y = rangeCheckedY(Y);
- }
- //大写的X,Y是公用属性
- public int X
- {
- get { return this.x; }
- set { this.y = rangeCheckedX(value); }
- }
- public int Y
- {
- get { return this.y; }
- set { this.y = rangeCheckedY(value); }
- }
- private static int rangeCheckedX(int x) { ... }
- private static int rangeCheckedY(int y) { ... }
- }
使用属性.
- ScreenPosition origin = new ScreenPosition ( 0, 0 ) ;
- int xpos = origin.X ; // 实际调用 origin.X.get
- origin.Y = 100 ; // 实际调用 origin.Y.set
只读属性 - 有get 没有 set .
只写属性 - 有set 没有 get
在接口中声明属性.
- 将get accessor 或 set accessor 主体替换成一个分号 .
- interface IScreenPosition
- {
- int X { get; set; }
- int Y { get; set; }
- }
既然有了Field(字段),又有了Property(属性),那么在OOP的过程中,什么时候用Field,什么时候用Property呢?
一般的原则是,类的封装性原则,Field为Private,类的实例中使用,而Property是类暴漏给外面的接口,可以进行读取,设置操作。
(以下为翻译文章)原文:http://msdn.microsoft.com/en-us/library/ms229006(v=vs.110).aspx
Property Design(属性的设计)
尽管property从技术上看和method很相似,但是在使用场景上却有很大的不同。property应该被看成一个智能的field,它具备field的使用语法,还拥有method的灵活性。
DO: 如果调用者不能修改property的值,那么创建一个get-only(只读) 的property。
请记住如果property是一个可变的引用类型(mutable reference type), 即使property是get-only,property的值还是可以被修改的。
DO NOT: 不要提供一个set-only的property, 或者setter被getter有更多的控制权限。
例如:不要使用有一个public的setter和一个protected 的getter。
DO:为所有的property提供一个合理的默认值,确保默认值不会导致安全漏洞和非常低效的代码。
DO: 运行property可以在任何顺序下被set, 即使导致临时的object的无效状态。
DO: 如果property的set会产生一个异常,那么将保留之前的一个值。
AVOID: 避免从propery getter中产生异常。