Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 构造函数链接顺序_C# - Fatal编程技术网

C# 构造函数链接顺序

C# 构造函数链接顺序,c#,C#,如果使用以下语法链接构造函数调用: public frmConfirm(): this(1) 何时调用重载构造函数?另外,是否有人可以确认,如果类是一个表单,那么在两个构造函数中调用InitializeComponent()会产生问题?链式构造函数将在定义构造函数的主体之前立即调用。生成的IL序列是对另一个构造函数的立即调用,然后是从构造函数中的语句生成的IL 因此,如果您链接到另一个构造函数,并且该构造函数调用了InitializeComponent(),则调用该构造函数的构造函数不应调用此

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

public frmConfirm(): this(1)

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

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

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

例如,给定此示例类:

class Foo {
    public int A, B;

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

    public Foo(int a) {
        A = a;
    }
}
这是生成的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
请注意,无参数构造函数在将2赋给B字段之前调用另一个构造函数。

首先调用
此(1)
构造函数


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

在这样的问题上寻找答案的地方是。在构造函数初始值设定项一节中,您可以阅读(重点是我的):

所有实例构造函数(除 类(对象)的隐式 包括对另一个的调用 实例构造函数立即 在构造函数主体之前

进一步阅读表明:

  • 如果构造函数具有形式为
    base(arguments)
    的实例构造函数初始值设定项,则将调用直接基类中的构造函数
  • 如果构造函数具有形式为
    this(参数)
    的实例构造函数初始值设定项,则将调用类本身中的构造函数
  • 如果未提供实例构造函数初始值设定项,将自动添加
    base()

@madmik3:编写代码来查看发生了什么事情确实很简单。问题是,这是否保证在所有情况下都会发生(不同的操作系统,不同版本的CLR)。一个相关的post-。MSIL不会导致循环引用吗?(我知道不会,但我不明白为什么)似乎.ctor()正在调用.ctor(int32a),反之亦然。有人能澄清为什么没有发生这种情况吗?@arviman
Foo:.ctor()
正在调用
Foo:.ctor(int32)
,但这反过来又调用
System.Object:.ctor()
,而不是
Foo:.ctor()