Effiective C# Item1 : 使用属性代替成员变量
2014-07-24 10:35
218 查看
Item1:Always Use Properties Instead of Accessible Data Members
属性是C#语言中一个很重要的特性,我们可以使用属性对成员进行封装。
从编译器的角度来看,属性就是针对成员变量两个方法:get_xxx和set_xxx,这一点和Java是很像的,当我们在Java中定义个成员变量,然后通过重构生成相应的属性时,对应的方法名就是get_xxx和set_xxx。
为什么要使用属性来代替成员变量呢?我认为从类的职责划分的角度进行理解会更好一些,当一个类向外公开一个访问入口时,这个入口可以是公开的方法、属性或者成员变量,那么从封装变化的观点来看,类本身应该对自身变量的异常进行处理,而不是由调用方进行处理。因此,如果是坚持使用公开的成员变量,那么对变量的异常处理,只能由调用方来进行处理,这样做是不合理的。一方面,同样的异常处理在多个调用方进行,会出现大量的重复代码,另一方面,当业务发生变化,成员变量的逻辑有改变时,需要修改每个调用该变量的地方,这将会是一件令人非常抓狂的事情。
使用属性代替成员变量,有以下好处:
可以在set或者get中对异常情况进行统一处理,或者可以在set和get中对多线程进行统一处理。
可以通过设置set和get的方式将属性置为可读写的,也可以通过只设置get不设置set的方式,将属性置为只读的,这样可以避免调用方对属性的值进行错误的赋值。
由于set和get可以看做是方法的形式,那么它们就可以使用方法的访问限制符,例如可以将set设置为private,将get设置为public,这样,对于属性来说,它的调用方还是不能为其赋值,从另外的角度实现了只读属性。当然还可以使用其他限制符,例如protected、internal等。
可以在接口中声明属性,也可以在抽象类中声明抽象属性。这样在进行框架设计时,可以为具体业务留出足够的空间。
我们可以对属性的外延进行扩充,进而讨论索引器,索引器的形式:this[int i]{set;get},索引器也包括set和get,同时"[]"中可以是数字,也可以是其他字符串。当我们通过索引器进行数据绑定时,要求"[]"中必须是数字。
使用属性会降低程序的性能吗?
一般来说,是不会的,首先,.NET程序运行时,是采用JIT的方式进行的,如果会影响性能,那么只能是在第一次运行的时候;其次,编译器在对属性进行编译时,会采用内联函数的方式,对set和get进行处理,这样的结果,和直接访问数据成员差别很小,基本可以忽略不计。
注意:当我们将类中公开的成员变量重构为属性后,需要重新编译所有使用到这个属性的类,因为这个重构的操作破坏了二进制的兼容性。
属性是C#语言中一个很重要的特性,我们可以使用属性对成员进行封装。
从编译器的角度来看,属性就是针对成员变量两个方法:get_xxx和set_xxx,这一点和Java是很像的,当我们在Java中定义个成员变量,然后通过重构生成相应的属性时,对应的方法名就是get_xxx和set_xxx。
为什么要使用属性来代替成员变量呢?我认为从类的职责划分的角度进行理解会更好一些,当一个类向外公开一个访问入口时,这个入口可以是公开的方法、属性或者成员变量,那么从封装变化的观点来看,类本身应该对自身变量的异常进行处理,而不是由调用方进行处理。因此,如果是坚持使用公开的成员变量,那么对变量的异常处理,只能由调用方来进行处理,这样做是不合理的。一方面,同样的异常处理在多个调用方进行,会出现大量的重复代码,另一方面,当业务发生变化,成员变量的逻辑有改变时,需要修改每个调用该变量的地方,这将会是一件令人非常抓狂的事情。
使用属性代替成员变量,有以下好处:
可以在set或者get中对异常情况进行统一处理,或者可以在set和get中对多线程进行统一处理。
可以通过设置set和get的方式将属性置为可读写的,也可以通过只设置get不设置set的方式,将属性置为只读的,这样可以避免调用方对属性的值进行错误的赋值。
由于set和get可以看做是方法的形式,那么它们就可以使用方法的访问限制符,例如可以将set设置为private,将get设置为public,这样,对于属性来说,它的调用方还是不能为其赋值,从另外的角度实现了只读属性。当然还可以使用其他限制符,例如protected、internal等。
可以在接口中声明属性,也可以在抽象类中声明抽象属性。这样在进行框架设计时,可以为具体业务留出足够的空间。
我们可以对属性的外延进行扩充,进而讨论索引器,索引器的形式:this[int i]{set;get},索引器也包括set和get,同时"[]"中可以是数字,也可以是其他字符串。当我们通过索引器进行数据绑定时,要求"[]"中必须是数字。
使用属性会降低程序的性能吗?
一般来说,是不会的,首先,.NET程序运行时,是采用JIT的方式进行的,如果会影响性能,那么只能是在第一次运行的时候;其次,编译器在对属性进行编译时,会采用内联函数的方式,对set和get进行处理,这样的结果,和直接访问数据成员差别很小,基本可以忽略不计。
注意:当我们将类中公开的成员变量重构为属性后,需要重新编译所有使用到这个属性的类,因为这个重构的操作破坏了二进制的兼容性。
相关文章推荐
- Effiective C# Item1 : 使用属性代替成员变量
- effective C#之 - 使用属性代替成员变量
- 使用属性代替可访问的成员变量
- C#类中属性与成员变量的使用小结
- Item 1: 尽可能的使用属性代替可访问的数据成员(Always Use Properties Instead of Accessible Data Members)
- 提高C#编程水平的50个要点 1.总是用属性 (Property) 来代替可访问的数据成员 2.在 readonly 和 const 之间,优先使用 readonly 3.在 as 和 强制类型转换之
- 对于C#中使用变量的“位” 来代替不同的意思 类似于二进制
- Effective C#:Item1:使用属性而不是可访问数据成员
- C#中属性和成员变量的区别说明
- 条款一 : 使用属性代替可访问的数据成员
- C# 字段、属性、成员变量
- C#属性和成员变量的区别?
- 条款1:使用属性代替可访问的数据成员(转)
- 使用公共静态属性的方式来代替公共静态字段(C#)
- 条款1:使用属性代替可访问的数据成员
- 《Effective C#》Item 4:使用Conditional属性来代替IF/ENDIF程序块
- VSTS小技巧之使用IDE的宏,自动为c#变量生成属性
- 为什么不直接使用成员变量而使用属性呢?
- 转:Effective C#》Item 4:使用Conditional属性来代替IF/ENDIF程序块
- Effective C# Item13:使用静态构造器初始化静态类成员