当继承包含带参数的构造函数的类时,派生类必须调用此构造函数。所以下面的代码不能编译:
public class DerivedClass : BaseClass
{
public DerivedClass(string callBase)
{
}
}
public class BaseClass
{
protected BaseClass(string callMe)
{
}
}
由于:
“BaseClass”类型不包含带“0”参数的构造函数
我们必须调用base(string)
构造函数:
public DerivedClass(string callBase)
: base(callBase)
{
}
一切都很好。
但是,当基类构造函数包含params
参数时:
public class DerivedClass : BaseClass
{
public DerivedClass(string callBase)
{
}
}
public class BaseClass
{
protected BaseClass(params string[] callMe)
{
}
}
现在我们可以同意BaseClass
仍然没有带0参数的构造函数,但上面的代码编译。
实际上,DerivedClass
构造函数的IL显示:
IL_0001: ldc.i4.0
IL_0002: newarr [mscorlib]System.String
IL_0007: call instance void BaseClass::.ctor(string[])
它隐式调用基础构造函数,其中包含params
参数的请求元素类型的空数组。
此外,当DerivedClass
不包含构造函数时,会为自动生成的无参数构造函数(“默认构造函数”)生成相同的IL。
为什么C#编译器会这样做,而不是生成与没有params
修饰符相同的警告?
来自C#6规范:
10.11.4默认构造函数
如果类不包含实例构造函数声明,则会自动提供默认实例构造函数。 该默认构造函数只是调用直接基类的无参数构造函数。如果这个类是抽象的 然后保护默认构造函数的已声明可访问性。否则,声明的可访问性 默认构造函数是public。因此,默认构造函数始终为
形式protected C(): base() {}
或
public C(): base() {}
强调我的。
但当然这仍然是正确的,因为base()
反过来被编译为base(new string[])
。
但是,在构造函数的情况下,我宁愿得到错误而不是隐式调用。