Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor Chaining Order

Tags:

c#

If you chain constructor calls using the syntax:

public frmConfirm(): this(1) 

when is the overloaded constructor called? Also, can somebody confirm that if the class is a form, problems will arise from having the InitializeComponent() call in both constructors?

like image 826
JeffE Avatar asked Jan 05 '11 22:01

JeffE


People also ask

Does order matter in constructor chaining?

Constructor chaining can be achieved in any order.

Does order matter in constructor chaining select one?

Rules of Constructor Chaining An expression that uses this keyword must be the first line of the constructor. Order does not matter in constructor chaining.

How is constructor chaining performed?

Constructor chaining is the process of calling a sequence of constructors. We can do it in two ways: by using this() keyword for chaining constructors in the same class. by using super() keyword for chaining constructors from the parent class.


2 Answers

The chained constructor will be called immediately prior to the body of the defining constructor. The IL sequence generated is an immediate call to the other constructor, followed by the IL generated from the statements in the constructor.

So if you chain to another constructor and that constructor calls InitializeComponent() the calling constructor should not call this method.

For example, given this sample class:

class Foo {     public int A, B;      public Foo() : this(1) {         B = 2;     }      public Foo(int a) {         A = a;     } } 

This is the generated IL:

  .class private auto ansi beforefieldinit Foo         extends [mscorlib]System.Object   {     .field  public  int32 A     .field  public  int32 B      // method line 1     .method public hidebysig  specialname  rtspecialname            instance default void '.ctor' ()  cil managed     {         .maxstack 8         IL_0000:  ldarg.0         IL_0001:  ldc.i4.1         IL_0002:  call instance void class Foo::'.ctor'(int32)         IL_0007:  ldarg.0         IL_0008:  ldc.i4.2         IL_0009:  stfld int32 Foo::B         IL_000e:  ret     } // end of method Foo::.ctor      // method line 2     .method public hidebysig  specialname  rtspecialname            instance default void '.ctor' (int32 a)  cil managed     {         .maxstack 8         IL_0000:  ldarg.0         IL_0001:  call instance void object::'.ctor'()         IL_0006:  ldarg.0         IL_0007:  ldarg.1         IL_0008:  stfld int32 Foo::A         IL_000d:  ret     } // end of method Foo::.ctor    } // end of class Foo 

Note that the no-arg constructor calls the other constructor before assigning 2 to the B field.

like image 144
cdhowie Avatar answered Sep 18 '22 17:09

cdhowie


The this(1) constructor is called first.

As far as your second question goes, because of the InitializeComponent and other issues with form inheritance, I'd suggest you use composition instead of inheritance.

like image 39
Jacob Avatar answered Sep 17 '22 17:09

Jacob