1. 概述
本章讨论类型中的各种属性。
2. 名词解释
① 属性:属性允许源代码用一个简化的语法来调用一个方法。
② 访问器方法:封装了字段访问的方法通常称为 访问器方法。
③ 自动实现属性(Automatically Implemented Property, AIP): C#提供的一种更简单的语法,用于 只是为了封装一个支持字段而创建一个属性的情况。
④ 内联(inline): 内联是将一个方法的代码直接编译到调用它的方法中。
3. 主要内容
3.1 无参属性
定义了get/set访问器以后,编译器会生成相应的get/set方法(以get_或set_为前缀)
3.1.1 自动实现的属性(AIP)
有以下弊端:
① 必须在每个构造器方法中显式初始化每个AIP。
② 在任何想要序列化或反序列化的类型中,都不要使用AIP功能。因为自动生成的名称会在每次编译时变化。
③ 调试时不能在AIP上设置断点。
3.1.2 合理定义属性
属性本质上就是一个方法,但是被用作字段的方式。以下是属性的弊端:
① 属性可以是只读或只写的,字段访问总是可读和可写的。如果定义属性,最好同时提供get和set访问器方法。
② 属性不能作为out或ref参数传递给方法。
③ 属性可能花费较长时间执行。如果需要线程同步,就不要使用属性。
④ 如果连续多次调用,属性每次都可能返回一个不同的值。
⑤ 属性可能造成明显的side effect。
⑥ 属性可能需要额外的内存,或者返回一个不正确的引用,指向不属于对象状态一部分的某个东西。
最后,建议老老实实的实现GetXxx和SetXxx方法,来代替属性。
3.1.3 对象和集合初始化器
3.1.4 匿名类型
var o1 = new { Name = "Jeff", Year = 1963};
3.1.5 System.Tuple类型
3.2 有参属性
C#用数组风格的语法来公开有参属性(索引器)。可将索引器看做C#开发人员重载[]操作符的一种方式。
3.3 调用属性访问器方法时的性能
对于简单的get/set访问器方法,JIT编译器会将代码内联。这样就不会有性能损失了。
3.4 属性访问器的可访问性
定义一个属性时,如果两个访问器方法需要具有不同的可访问性,C#语法要求必须为属性本身指定限制最不大的那种,然后,在两个访问器中,只能选择一个来应用限制较大的那一种可访问性。
public String Name { get { return m_name; } protected set { m_name = value; } }
3.5 泛型属性访问器方法
C#不允许属性访问器具有泛型参数。
4. 总结