为什么会调用父类的构造函数?

4
我有一个抽象类Example。另一个泛型类UsesExample将其用作约束,并带有new()约束。稍后,我创建了Example类的子类ExampleChild,并与泛型类一起使用。但是不知何故,在泛型类中的代码尝试创建新副本时,它调用的是父类中的构造函数,而不是子类中的构造函数。这是为什么? 以下是代码:
abstract class Example {

    public Example() {
        throw new NotImplementedException ("You must implement it in the subclass!");
    }

}

class ExampleChild : Example {

    public ExampleChild() {
        // here's the code that I want to be invoken
    }

}

class UsesExample<T> where T : Example, new() {

    public doStuff() {
        new T();
    }

}

class MainClass {

    public static void Main(string[] args) {

        UsesExample<ExampleChild> worker = new UsesExample<ExampleChild>();
        worker.doStuff();

    }

}
3个回答

8
当您创建一个对象时,所有构造函数都会被调用。首先,基类构造函数构造对象,使得基类成员被初始化。稍后,层次结构中的其他构造函数将被调用。
此初始化可能会调用静态函数,因此即使抽象基类没有数据成员,调用其构造函数也是有意义的。

你对此确定吗?我不确定C#是否需要显式调用父类构造函数,但通常在 Java 中需要通过 super() 调用。 - MK.
他是正确的,你可以在我答案中提供的链接中查看(其中一个是 MSDN)。 - YavgenyP
@MK:没错。在C#中,父类构造函数总是会被调用。如果你没有指定: this()或者: base()的调用,它会自动调用无参构造函数。 - Guffa
1
当然,基类的默认构造函数会被调用。在Java中也是如此。 - MK.

8
每当你创建一个派生类的新实例时,基类的构造函数会隐式调用。在你的代码中,
public ExampleChild() {
    // here's the code that I want to be invoked
}

变成了:

public ExampleChild() : base() {
    // here's the code that I want to be invoked
}

由编译器完成。

你可以在Jon Skeet关于C#构造函数的详细博客文章中了解更多信息。


2
在派生类中,如果没有使用base关键字显式调用基类构造函数,则默认构造函数(如果存在)会被隐式调用。
来源:msdn 此外,您还可以在这里阅读。

1
并且需要澄清的是,如果没有对基类的显式调用,并且它没有可访问的默认构造函数,则代码将无法编译。 - Guffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接