深入理解C#(十五)
*第八章(C# 3:用智能的编译器来防错)
自动实现的属性
简化普通属性的代码
普通属性:可读/可写并将值存储到一个非常直观的私有变量中的属性。
1 | public string Name{get;set;} |
仍然可以为取值和赋值方法指定不同的访问权限。
静态自动属性:取值方法是共有的,赋值方法是私有的,且赋值方法只能在类型初始化程序中使用。
定义struct时,使用自动属性,需要显式地调用无参构造函数
1 | public struct Foo |
自动属性仍有几个小问题:
- 没办法在声明时,设定初始的默认值
- 没法把它们设定成真正的只读属性(使用私有赋值方法来解决)
隐式类型的局部变量
使用var声明局部变量
var并没有把C#变成动态类型或者弱类型的语言,只是类型由编译器推断
编译器获取初始化表达式在编译时的类型,并使变量也具有那种类型。
隐式类型的限制
只有在一下情况能使用:
- 局部变量,不是静态字段和实例字段
- 声明的同时被初始化
- 初始化表达式不是方法组和匿名函数
- 初始化表达式不是null
- 语句中之声明了一个变量
- 初始化表达式不包含正在声明的变量
对于第三点,显示声明变量是可以的,如:var starter = (ThreadStart)delegate(){ Console.WriteLine();}
对于null也可以做强制类型转换,但是无意义。
最常见应用:用方法调用的结果来初始化一个变量。
隐式类型的优缺点
优点:增强可读性,改变代码重心
缺点:类型不明确
简化的初始化
定义示例类型
new Person{Name="Jon",Age=36}
为嵌入对象设置属性
1 | Person tom=new Person("Tom"){ |
集合初始化程序
- 使用集合初始化程序来创建新集合
List<string> names=new List{ "Holly","Jon","Tom"};
任何实现了IEnumerable类型,只要它为初始化列表中出现的每个元素都提供了一个恰当的公共的Add方法,就可以使用这个特性。 - 在其他对象初始化程序中填充集合
隐式类型的数组
对于void MyMethod(string[] names)
C#3 这样使用:MyMethod(new[] {"Holly","Jon","Tom"});
匿名类型
实例:使用匿名类型,填充数组
1 | var family = new[] |
family中所有人具有相同的类型,否则编译器无法推断出何时类型。
匿名类型的成员
- 一个获取所有初始值的构造函数
- 共有的只读属性
- 属性的私有只读字段
- 重写的Equals、GethashCode和ToString
投影初始化程序
实际使用时,往往希望从别的对象复制属性用以新建一个新的对象。 例如:new { Name=person.Name,IsAdult=(person.Age>=18)}
C# 3支持一种简化的语法:如果不指定属性名称,而只指定用于求指的表达式,它会使用表达式的最后一个部分作为名称,前提是它只是一个简单字段或属性。
应用:new { person.Name, IsAdult=(Person.Age>=18)}