构造函数的代码膨胀问题

1. 类1

    public class A
    {
        private Int32 x = 15;
    }

查看其默认的无参构造函数形成的IL Code:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       16 (0x10)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   15
  IL_0003:  stfld      int32 ConsoleApplication9.A::x
  IL_0008:  ldarg.0
  IL_0009:  call       instance void [mscorlib]System.Object::.ctor()
  IL_000e:  nop
  IL_000f:  ret
} // end of method A::.ctor

----把15赋给变量x(初始化),然后调用父类Object中的无参构造函数

2. 类2

public class MyClass
    {
        private String name = "josh";
        private Int32 x = 15;

        public MyClass(String sname)
        {
            this.name = sname;
        }

        public MyClass(Int32 sx)
        {
            this.x = sx;
        }
    }

该类中有两个重载的构造函数,分别查看这两个构造函数所形成的IL Code:

带String类型参数的构造函数IL code:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(string sname) cil managed
{
  // Code size       36 (0x24)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldstr      "josh"
  IL_0006:  stfld      string ConsoleApplication9.MyClass::name
  IL_000b:  ldarg.0
  IL_000c:  ldc.i4.s   15
  IL_000e:  stfld      int32 ConsoleApplication9.MyClass::x
  IL_0013:  ldarg.0
  IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0019:  nop
  IL_001a:  nop
  IL_001b:  ldarg.0
  IL_001c:  ldarg.1
  IL_001d:  stfld      string ConsoleApplication9.MyClass::name
  IL_0022:  nop
  IL_0023:  ret
} // end of method MyClass::.ctor

带Int32类型参数的构造函数IL code:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(int32 sx) cil managed
{
  // Code size       36 (0x24)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldstr      "josh"
  IL_0006:  stfld      string ConsoleApplication9.MyClass::name
  IL_000b:  ldarg.0
  IL_000c:  ldc.i4.s   15
  IL_000e:  stfld      int32 ConsoleApplication9.MyClass::x
  IL_0013:  ldarg.0
  IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0019:  nop
  IL_001a:  nop
  IL_001b:  ldarg.0
  IL_001c:  ldarg.1
  IL_001d:  stfld      int32 ConsoleApplication9.MyClass::x
  IL_0022:  nop
  IL_0023:  ret
} // end of method MyClass::.ctor

----不难发现这两个构造函数都会形成一样的IL code来初始化实例变量,即初始化重复操作,如果一个类中有多个这样的重载构造函数,那么很可能会形成代码膨胀问题

3. 类3(方法的改进)

    public class TestClass
    {
        private String name;
        private Int32 x;

        public TestClass()
        {
            name = "josh";
            x = 15;
        }

        public TestClass(String sname)
            : this()
        {
            name = sname;
        }

        public TestClass(Int32 sx)
            : this()
        {
            x = sx;
        }
    }

----在定义实例变量时只定义不初始化,由一个构造函数专门来初始化它们,其他构造函数只需调用该构造函数即可

查看IL Code:

a. 无参构造函数
.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       29 (0x1d)
  .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      "josh"
  IL_000e:  stfld      string ConsoleApplication9.TestClass::name
  IL_0013:  ldarg.0
  IL_0014:  ldc.i4.s   15
  IL_0016:  stfld      int32 ConsoleApplication9.TestClass::x
  IL_001b:  nop
  IL_001c:  ret
} // end of method TestClass::.ctor

b. 带String参数的构造函数
.method public hidebysig specialname rtspecialname 
        instance void  .ctor(string sname) cil managed
{
  // Code size       17 (0x11)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void ConsoleApplication9.TestClass::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.1
  IL_000a:  stfld      string ConsoleApplication9.TestClass::name
  IL_000f:  nop
  IL_0010:  ret
} // end of method TestClass::.ctor

c. 带Int32参数的构造函数
.method public hidebysig specialname rtspecialname 
        instance void  .ctor(int32 sx) cil managed
{
  // Code size       17 (0x11)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void ConsoleApplication9.TestClass::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.1
  IL_000a:  stfld      int32 ConsoleApplication9.TestClass::x
  IL_000f:  nop
  IL_0010:  ret
} // end of method TestClass::.ctor

 

 

posted on 2013-02-28 23:14  Gcam  阅读(186)  评论(0编辑  收藏  举报

导航