如果您使用语法连锁构造函数调用:构造链接订购
public frmConfirm(): this(1)
时被称为重载的构造函数?另外,有人可以证实,如果这个类是一个表单,在两个构造函数中都有InitializeComponent()调用会产生问题吗?
如果您使用语法连锁构造函数调用:构造链接订购
public frmConfirm(): this(1)
时被称为重载的构造函数?另外,有人可以证实,如果这个类是一个表单,在两个构造函数中都有InitializeComponent()调用会产生问题吗?
链接的构造函数将在定义构造函数的主体之前立即被调用。生成的IL序列是立即对其他构造函数的call
,随后是从构造函数中的语句生成的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场之前调用其他构造。
首先调用this(1)
构造函数。
至于第二个问题,由于InitializeComponent
和其他形式继承问题,我建议你使用组合而不是继承。
我知道表单继承的一些问题,但它是我的项目的最佳解决方案 – JeffE 2011-01-05 22:24:05
在这样的问题上寻找答案的地方是C# Language Specification。在第10.11.1 ,构造函数初始化你可以阅读(重点是我的):
所有实例构造函数(除了 那些类对象)隐含 包括另一 实例构造之前调用立即 构造函数体。
此外读数表明:
base(arguments)
的实例构造函数的初始化,从直接基类的构造将被调用。this(argument)
的实例构造函数初始值设定项,则将调用该类中的构造函数。base()
。感谢您将c#语言规范引入我的注意 – Ronnie 2016-03-08 13:43:22
@ madmik3:它确实很容易编写代码来查看会发生什么。那么问题是,是否确保*在所有情况下都会发生(不同的操作系统,不同版本的CLR)。 – 2011-01-05 22:23:58
一个相关的帖子 - [C#构造函数执行顺序](https://stackoverflow.com/q/1882692/465053)。 – RBT 2018-02-14 11:48:43