It is said in Jeff's book that initialization work of a field together with its definition will be done in ctors. If you have several ctors, the field will be initialized in these ctors seperately. See following example:
    public partial class Window1 : Window
   {
       public class InnerObject
       {
           public InnerObject()
           {
               Debug.WriteLine("InnerObject() ctor.");
           }
       }
       public class Foo
       {
           private int field = 99;
           private InnerObject innerObject = new InnerObject();
           public Foo()
           {
           }
           public Foo(int a)
           {
           }
       }
       public Window1()
       {
           InitializeComponent();
           Foo foo1 = new Foo();
           Foo foo2 = new Foo(12);
       }
   }
.method public hidebysig specialname rtspecialname
       instance void  .ctor(int32 a) cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
.method public hidebysig specialname rtspecialname
       instance void  .ctor() cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
        public class Foo
       {
           private int field = 99;
           private InnerObject innerObject = new InnerObject();
           public Foo()
           {
           }
           public Foo(int a) : this()
           {
           }
       }
.method public hidebysig specialname rtspecialname
       instance void  .ctor(int32 a) cil managed
{
 // Code size       10 (0xa)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  call       instance void FieldInitialization.Window1/Foo::.ctor()
 IL_0006:  nop
 IL_0007:  nop
 IL_0008:  nop
 IL_0009:  ret
} // end of method Foo::.ctor
.method public hidebysig specialname rtspecialname
       instance void  .ctor() cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
As you can see initialization code in Foo(int a) is gone. C# compiler did the optimization. I think, it's the better way of initializing fields, though Jeff suggest to do initialization expilicitly in default ctor.
But, I have a question, can we rely on this optimization behavor of C# compiler?
 
 
No comments:
Post a Comment