CLR Via C# 3rd 阅读摘要 -- Chapter 10 - Properties
Parameterless Properties
1. 建议所有的字段(fields) 设置成private;
2. smart fields:具有特定逻辑的字段;
3. CLR支持static,instance,abstract,virtual的属性;
4. 编译器根据属性名称自动生成前缀有get_和set_的方法;
5. System.Reflection.PropertyInfo,CLR在运行期不使用这些元数据,而只使用访问器方法。
--Automatically Implemented Properties
1. AIPs:automatically Implemented Properties。public string Name {get; set; }
2. 使用AIP的注意点:
- 构造器方法中必须显示的初始化每一个AIP;
- 如果需要序列化和反序列化,就不要使用AIP;
- 调试的时候,不能在AIP中设置断点。
--Defining Properties Intelligently
1. Property与Field:
- property可以只读、只写;field总是可读写;
- property会抛出异常;field就不会;
- property不能用作方法的out、ref 参数;field就可以;
- property的方法可能会执行很长时间;field总是立即完成;
- 当需要线程同步时不要使用property,最好用method;
- 如果class需要被远程访问,也是最好用method,而不要用property;
- 从MarshalByRefObject继承下来的class,就别再用property;
- property返回的值可能每次会不一样,比如Enviroment.TickCount;DateTime.Now;
- property方法可能引发可观察的副作用(不同的property影响同一个装他),field不会;
- property方法可能需要额外的内存来返回一个引用,而该引用实际上不是对象状态的一部分,因此改变这个返回值并不会对原有对象生效。
2. [Debugging]Enable Property Evaluation And Other Implicit Function Calls选项开关。
--Object and Collection Initializers
1. Employee e = new Employee { Name = "Jeff", Age = 45 };
2. var table = new Dictionary<string, int> {{ "Jeffrey", 1 }, { "Kristin", 2 }, { "Aidan", 3 }, { "Grant", 4 }};
--Anonymous Types
1. tuple type:等于python的tuple类型;
2. 匿名类型,编译器覆盖了Object.Equals, GetHashCode, ToString;
3. LINQ
--The System.Tuple Type
1. 跟匿名类型一样,一旦Tuple创建了,就不可变;
2. System.Dynamic.EnpandoObject,可动态扩展的对象:dynamic e = new System.Dynamic.ExpandoObject()。
Parameterful Properties
1. parameterless properties:C#(indexers,this[...])、Visual Basic(default properties);
2. 带参数的属性至少要有一个参数,可以是除void的任何类型;
3. C#不支持静态indexer属性,虽然CLR支持静态参数化属性;
4. System.Runtime.CompilerServices.IndexerNameAttribute重命名indexer名称,但是IndexerNameAttribute不是CLI和C#ECMA标准的一部分;
5. C#可以将indexer看作是[]操作符重载;
6. System.Reflection.DefaultMemberAttribute,选择一个参数化的属性作为缺省属性。
The Performance of Calling Property Accessor Methods
1. 对于简单的get和set属性访问器方法,JIT采用内联编译;
2. debug构建时,由于内联编译难以调试,所以JIT在调试代码时并不内联属性方法;
Property Accessor Accessibility
1. 可以给set和get设置不同的访问修饰符。
Generic Property Accessor Methods
1. C#可不允许泛型的property方法。主要原因是从概念上来说,property是不假定有行为的。如果要泛型,那么用方法。
本章小结
本章阐明了两种属性:无参数属性和参数化属性。 详细解释了AIP属性,匿名类型,Tuple的实现机制以及需要注意的地方。如何定义参数化的属性,以及如何重命名indexer和设置默认的indexer。对比了属性和字段的区别,以及在使用属性时的性能问题。最后讲了属性方法的访问修饰符,以及为何不能用泛型属性。