构造函数链序

发布于 2024-10-10 05:59:52 字数 181 浏览 4 评论 0原文

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

public frmConfirm(): this(1)

何时调用重载构造函数?

另外,有人可以确认,如果该类是一个表单,那么在两个构造函数中调用 InitializeComponent() 就会出现问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

秋日私语 2024-10-17 05:59:52

链式构造函数将在定义构造函数的主体之前立即调用。生成的 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 字段之前调用另一个构造函数。

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.

隔岸观火 2024-10-17 05:59:52

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

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

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.

昇り龍 2024-10-17 05:59:52

寻找此类问题答案的地方是 C# 语言规范。在构造函数初始值设定项部分中,您可以阅读(重点是我的):

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


进一步阅读表明:

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

The place to look for answers on a question like this is the C# Language Specification. In the section Constructor initializers you can read (emphasis is mine):

All instance constructors (except
those for class object) implicitly
include an invocation of another
instance constructor immediately
before
the constructor-body.

Further reading shows that:

  • if the constructor has an instance constructor initializer of the form base(arguments), a constructor from the direct base class will be invoked.
  • if the constructor has an instance constructor initializer of the form this(argument), a constructor in the class itself will be invoked.
  • if no instance constructor initializer is provided, base() will be added automatically.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文