属性尚未初始化 C#3.0之自动属性和对象初始化器
C#3.0之自动属性和对象初始化器
C# 中定义属性更加方便 不用再在像之前的版本那样的繁琐 需要先定义存储数据的字段 然后再定义属性器 现在只需要定义属性器就可以了 其它的有编译器自动为我们完成 就可以省去定义字段时需要的那些时间 在对象初始化的时候我们可在对象构造的时候实现对象属性的初始化工作 和集合初始化类似匿名属性
定义属性如下
public class Employee { public int Id { get; set; } public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string BirthDate { get; set; } }
在C# 之前的写法如下

public class Employee { private int _id; private string _name; private string _sex; private int _age; private string _birthDate; public int Id { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } public string Sex { get { return _sex; } set { _sex = value; } } public int Age { get { return _age; } set { _age = value; } } public string BirthDate { get { return _birthDate; } set { _birthDate = value; } } }
仅从代码量上就前者比后者减少了 / 的代码 这对提高效率是显而易见的 那么这些代码都到哪里去了呢?其实那些额外的代码都是由编译器为我们完成的 编译器会将那些我们 省去 的代码编译成托管IL代码的时候补进去 两者中代码在最终生成的IL代码的体积是差不多的
上图中的IL代码中我们看到了 k_BackingField之类的字段就是编译器自动产生的字段代码
对象初始化器
原来的对象初始化都要进行先创建构造方法 然后才能进行成员的相关操作 C# 提供了对象成员的直接初始化的能力 和初始化一个集合或者是数组一样来初始化对象
相对来看 通过对象初始化器对上面的的Employee类进行进行调用
Employee employee = new Employee { Id = Name = 蓝之风 Age = BirthDate = Sex = 男 }; Console WriteLine( 编号;{ } employee Id); Console WriteLine( 姓名:{ } employee Name); Console WriteLine( 年龄:{ } employee Age); Console WriteLine( 生日:{ } employee BirthDate); Console WriteLine( 性别:{ } employee Sex); Console WriteLine( 请按任意键继续 ); Console ReadLine();
这句
Employee employee = new Employee { Id = Name = 蓝之风 Age = BirthDate = Sex = 男 };
就是对象的初始化 看到代码很简洁 输出的结果如下
在C# 之前的做法是
Employee employee = new Employee();employee Id = ;employee Name = 蓝之风 ;employee Age = ;employee BirthDate = ;employee Sex = 男 ; Console WriteLine( 编号;{ } employee Id);Console WriteLine( 姓名:{ } employee Name);Console WriteLine( 年龄:{ } employee Age);Console WriteLine( 生日:{ } employee BirthDate);Console WriteLine( 性别:{ } employee Sex);Console WriteLine( 请按任意键继续 ); Console ReadLine();
或者通过重载构造方法的方式来初始化这些属性 二者的达到的效果是相同的 但是前者使用起来方便了些 代码量减少了许多 这个过程是怎么完成的呢?其实C#本身并没有太大的变化 这些都是在语法上的一些改变 使得编写代码的时候更方便效率更高 把一些编译器可以推断出来完成的工作让编译器来做了 编译器在编译程序的时候将我们没有实现的代码替我们实现来生成IL代码的
method private hidebysig static void Main(string[] args) cil managed{ entrypoint // 代码大小 ( xaf) maxstack locals init ([ ] class CS Employee employee [ ] class CS Employee <>g__initLocal ) IL_ : nop IL_ : newobj instance void CS Employee:: ctor() IL_ : stloc IL_ : ldloc IL_ : ldc i IL_ : callvirt instance void CS Employee::set_Id(int ) IL_ e: nop IL_ f: ldloc IL_ : ldstr bytearray (DD B E CE ) // KN IL_ : callvirt instance void CS Employee::set_Name(string) IL_ a: nop IL_ b: ldloc IL_ c: ldc i s IL_ e: callvirt instance void CS Employee::set_Age(int ) IL_ : nop IL_ : ldloc IL_ : ldstr IL_ a: callvirt instance void CS Employee::set_BirthDate(string) IL_ f: nop IL_ : ldloc IL_ : ldstr bytearray ( ) // u IL_ : callvirt instance void CS Employee::set_Sex(string) IL_ b: nop IL_ c: ldloc IL_ d: stloc IL_ e: ldstr bytearray ( F F B B D ) // S; { } IL_ : ldloc IL_ : callvirt instance int CS Employee::get_Id() IL_ : box [mscorlib]System Int IL_ e: call void [mscorlib]System Console::WriteLine(string object) IL_ : nop IL_ : ldstr bytearray (D D A B D ) // Y T: { } IL_ : ldloc IL_ a: callvirt instance string CS Employee::get_Name() IL_ f: call void [mscorlib]System Console::WriteLine(string object) IL_ : nop IL_ : ldstr bytearray ( E F A B D ) // t^ : { } IL_ a: ldloc IL_ b: callvirt instance int CS Employee::get_Age() IL_ : box [mscorlib]System Int IL_ : call void [mscorlib]System Console::WriteLine(string object) IL_ a: nop IL_ b: ldstr bytearray ( F E A B D ) // u e: { } IL_ : ldloc IL_ : callvirt instance string CS Employee::get_BirthDate() IL_ : call void [mscorlib]System Console::WriteLine(string object) IL_ b: nop IL_ c: ldstr bytearray ( B A B D ) // `+R: { } IL_ : ldloc IL_ : callvirt instance string CS Employee::get_Sex() IL_ : call void [mscorlib]System Console::WriteLine(string object) IL_ c: nop IL_ d: ldstr bytearray (F B FB E F E E E ED E E // c N a~ ~ E E ) // IL_ a : call void [mscorlib]System Console::WriteLine(string) IL_ a : nop IL_ a : call string [mscorlib]System Console::ReadLine() IL_ ad: pop IL_ ae: ret} // end of method Program::Main
从上面的IL代码中可以清晰的看到 首先创建了Employee的实例 然后才对相关的属性进行赋值操作的
总结
lishixinzhi/Article/program/net/201311/13185