构造函数链接顺序

Jef*_*ffE 37 c#

如果使用以下语法链接构造函数调用:

public frmConfirm(): this(1)
Run Code Online (Sandbox Code Playgroud)

何时重载的构造函数被调用?此外,有人可以确认,如果类是一个表单,在两个构造函数中调用InitializeComponent()会产生问题吗?

cdh*_*wie 44

链接构造函数将在定义构造函数的主体之前立即调用.生成的IL序列call对另一个构造函数是立即的,然后是从构造函数中的语句生成的IL.

因此,如果链接到另一个构造函数并且构造函数调用InitializeComponent()调用构造函数,则不应调用此方法.

例如,给定此示例类:

class Foo {
    public int A, B;

    public Foo() : this(1) {
        B = 2;
    }

    public Foo(int a) {
        A = a;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是生成的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
Run Code Online (Sandbox Code Playgroud)

请注意,no-arg构造函数在将2分配给B字段之前调用其他构造函数.

  • @arviman`Foo:.ctor()`正在调用`Foo:.ctor(int32)`,但它反过来调用`System.Object:.ctor()`,***不是***`Foo:.ctor ()`. (4认同)

Jac*_*cob 11

this(1)构造函数首先被调用.

至于你的第二个问题,由于InitializeComponent表单继承的其他问题,我建议你使用组合而不是继承.


Fre*_*örk 8

在这样的问题上寻找答案的地方是C#语言规范.在第10.11.1节中,您可以阅读构造函数初始值设定项(重点是我的):

所有实例构造函数(类对象除外)都隐式地包含在构造函数体之前的另一个实例构造函数的调用.

进一步阅读表明:

  • 如果构造函数具有表单的实例构造函数初始值设定项base(arguments),则将调用直接基类的构造函数.
  • 如果构造函数具有表单的实例构造函数初始值设定项this(argument),则将调用类本身的构造函数.
  • 如果没有提供实例构造函数初始值设定项,base()将自动添加.