上下文:c#中变量的内敛赋值其实是在构造函数中完成的,JIT会把变量的赋值语句放入每个构造函数开始的位置,因此,当类中有很多变量使用内联赋值,同时类也有多个构造函数的时候,实际编译生成的代码量会以乘法的方式叠加。比如一个类中有3个变量使用内联赋值,有4个构造函数,那么实际生成的赋值语句的数量将达到3x4=12句。
结论:尽量避免使用内联赋值,优先使用构造函数内赋值
类代码如下:
public class Cat
{
private string name;
public Cat()
{
}
public Cat(string _name)
{
name = _name;
}
public Cat(int _notuse)
{
name = "Hello Kitty";
}
public void Shout()
{
Console.WriteLine(name+" is now nyan nyan");
}
}
IL生成的代码如下:
//public Cat(string _name)
.method public hidebysig specialname rtspecialname
instance void .ctor(string _name) cil managed
{
// Code size 17 (0x11)
.maxstack 8
IL_0000: ldarg.0//load argument 0,即,将this指针压栈
IL_0001: call instance void [mscorlib]System.Object::.ctor()//使用this并调用object构造函数
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0//将this指针压栈
IL_0009: ldarg.1//将_name压栈
IL_000a: stfld string DLLTest.Cat::name//将栈顶的值赋给name
IL_000f: nop
IL_0010: ret//返回
} // end of method Cat::.ctor
//public Cat(int _notuse)
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 _notuse) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldstr "Hello Kitty”//将”Hello Kitty”压栈
IL_000e: stfld string DLLTest.Cat::name
IL_0013: nop
IL_0014: ret
} // end of method Cat::.ctor
//public Cat()
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: nop
IL_0009: ret
} // end of method Cat::.ctor
从上面3个构造函数的IL代码可以看出,当变量不使用内联赋值的时候,构造函数内不会自行补充赋值语句
下面将贴上内联赋值的Cat
public class Cat
{
private string name="Hello Tom";
public Cat()
{
}
public Cat(string _name)
{
name = _name;
}
public Cat(int _notuse)
{
name = "Hello Kitty";
}
public void Shout()
{
Console.WriteLine(name+" is now nyan nyan");
}
}
其构造函数分别是:
.method public hidebysig specialname rtspecialname
instance void .ctor(string _name) cil managed
{
// Code size 28 (0x1c)
.maxstack 8
IL_0000: ldarg.0//this压栈
IL_0001: ldstr "Hello Tom”//将”Hello Tom”压栈
IL_0006: stfld string DLLTest.Cat::name//将”Hello Tom”赋值给this.name
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: nop
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: stfld string DLLTest.Cat::name
IL_001a: nop
IL_001b: ret
} // end of method Cat::.ctor
其他构造函数中同样会增加赋值的那三句
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 _notuse) cil managed
{
// Code size 32 (0x20)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldstr "Hello Tom"
IL_0006: stfld string DLLTest.Cat::name
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: nop
IL_0013: ldarg.0
IL_0014: ldstr "Hello Kitty"
IL_0019: stfld string DLLTest.Cat::name
IL_001e: nop
IL_001f: ret
} // end of method Cat::.ctor
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldstr "Hello Tom"
IL_0006: stfld string DLLTest.Cat::name
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: nop
IL_0013: nop
IL_0014: ret
} // end of method Cat::.ctor