C#3.0 为我们带来什么(3) —— 初始化器
c#2.0
Employee e1;
private void ee1()
{
e1 = new Employee(1);
e1.Age = 25;
e1.Name = "james";
}
c#3.0
Employee 2;
private void ee2()
{
e2 = new Employee(2) { Age = 25, Name = "james" };
}
与自动属性一样,初始化器的c#3.0的最大特点就是语法简化。
来看下IL代码
c#2.0
.method private hidebysig instance void ee1() cil managed
{
// 代码大小 45 (0x2d)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: newobj instance void WindowsFormsApplication1.Employee::.ctor(int32)
IL_0008: stfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_000d: ldarg.0
IL_000e: ldfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_0013: ldc.i4.s 25
IL_0015: callvirt instance void WindowsFormsApplication1.Employee::set_Age(int32)
IL_001a: nop
IL_001b: ldarg.0
IL_001c: ldfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_0021: ldstr "james"
IL_0026: callvirt instance void WindowsFormsApplication1.Employee::set_Name(string)
IL_002b: nop
IL_002c: ret
} // end of method TestInitializer::ee1
c#3.0
.method private hidebysig instance void ee2() cil managed
{
// 代码大小 37 (0x25)
.maxstack 3
.locals init ([0] class WindowsFormsApplication1.Employee '<>g__initLocal0')
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.2
IL_0003: newobj instance void WindowsFormsApplication1.Employee::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.s 25
IL_000c: callvirt instance void WindowsFormsApplication1.Employee::set_Age(int32)
IL_0011: nop
IL_0012: ldloc.0
IL_0013: ldstr "james"
IL_0018: callvirt instance void WindowsFormsApplication1.Employee::set_Name(string)
IL_001d: nop
IL_001e: ldloc.0
IL_001f: stfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e2
IL_0024: ret
} // end of method TestInitializer::ee2
c#2.0中是这样来赋给age值的
IL_0008: stfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
(将参数压入堆栈)
IL_000d: ldarg.0
IL_000e: ldfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_0013: ldc.i4.s 25
c#3.0是这样的
IL_0008: stloc.0(从堆栈中弹出到局部变量)
IL_0009: ldloc.0
IL_000a: ldc.i4.s 25
也就是e1的对象载入简化了。看代码大小也能发现新写法的优势。
对应的就是集合初始化
c# 2.0
List<Employee> list1 = new List<Employee>();
list1.Add(e1);
c# 3.0
List<Employee> list2 = new List<Employee>
{
new Employee(3) { Age = 25, Name = "james" },
new Employee(4) { Age = 26, Name = "tony" }
};
对应的IL
c#2.0
.method public hidebysig instance void dd() cil managed
{
// 代码大小 21 (0x15)
.maxstack 2
.locals init ([0] class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee> list1)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee>::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldarg.0
IL_0009: ldfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee>::Add(!0)
IL_0013: nop
IL_0014: ret
} // end of method TestInitializer::dd
c#3.0
.method public hidebysig instance void newdd() cil managed
{
// 代码大小 23 (0x17)
.maxstack 2
.locals init ([0] class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee> list2,
[1] class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee> '<>g__initLocal1')
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee>::.ctor()
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldarg.0
IL_0009: ldfld class WindowsFormsApplication1.Employee WindowsFormsApplication1.TestInitializer::e1
IL_000e: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<class WindowsFormsApplication1.Employee>::Add(!0)
IL_0013: nop
IL_0014: ldloc.1
IL_0015: stloc.0
IL_0016: ret
} // end of method TestInitializer::newdd
两个的init是不同的,至于为什么3.0里会由编译器init出来第二个参数我还不大明白,还请各位看客指点。难道还会真的倒退了?
看到这里大家也该明白如何写代码才是最好的了吧。