C# 为什么在克隆数据表时会调用这么多构造函数?

C# 为什么在克隆数据表时会调用这么多构造函数?,c#,constructor,datatable,C#,Constructor,Datatable,求求你,救命! 我有一些继承的类,如下所示: public class DataTableA : DataTable { // ... public DataTable CloneMe() { DataTable table = this; return table.Clone(); } } public class DataTableB : DataTableA { // ... } public class Data

求求你,救命! 我有一些继承的类,如下所示:

public class DataTableA : DataTable
{
    // ...
    public DataTable CloneMe()
    {
        DataTable table = this;
        return table.Clone();
    }
}

public class DataTableB : DataTableA
{
    // ...
}

public class DataTableC : DataTableB
{
    // ...

    public void Test()
    {
        DataTable table = this.CloneMe(); 
    }
}
当我调用方法测试类DataTableC时,必然会调用以下构造函数:

数据表的构造函数 DataTableA的构造函数 DataTableB的构造函数 DataTableC的构造函数
但是为什么呢?我只希望调用DataTable的构造函数。

一般来说,当创建类型X的实例时,并且该类型具有基类Y,那么Y的构造函数将在X的构造函数之前被调用。这种想法在任何继承长度上都会继续

因此,在您的例子中,为了创建DataTableC的实例,需要首先调用DataTableB的构造函数。在调用DataTableB的构造函数之前,需要先调用DataTableA的构造函数,这同样需要运行DataTable的构造函数

这是创建新实例时的正常行为。但是您在这里使用的是DataTable.Clone,那么您到底在哪里创建DataTableC的新实例呢

这可以归结为一个问题。在内部,它使用,它本身使用反射来创建当前类型的新实例:

protected virtual DataTable CreateInstance() {
    return (DataTable) Activator.CreateInstance(this.GetType(), true);
}
在您的例子中,由于当前类型是DataTableC,因此正在创建DataTableC的一个新实例,这解释了为什么要调用所有这些构造函数

public DataTable CloneMe()
{
  return new DataView(this, "0=1", null, DataViewRowState.CurrentRows).ToTable();
}

此方法克隆DataTable或派生类的任何对象,而不创建DataTableC DataTableA、DataTableB对象。仅显式DataTable对象。

因为继承就是这样工作的?调用派生类的构造函数时发生的第一件事是它调用其父类的构造函数。@john,除非您为派生类编写一个特定的构造函数,而不使用:base@goaty如果你没有明确地调用base,它就是隐式调用的。@john right,我的badno,john,我没有调用派生类的构造函数,事实上我只调用了最高DataTable类的Clone方法。poke,似乎只有您了解matterIt对DataTable如此奇怪的行为的真相。Clone方法,我如何调用Clone来获取DataTable而不是DataTableC,但列结构必须来自DataTableC?实际上,这是一个相当聪明的实现。为什么需要显式数据表?DataTableC也是DataTable。因此,只需将克隆对象用作DataTable。不,不,我需要一个明确的DataTable,因为DataTableC包含许多其他对象,我没有创建这些对象。然后您需要自己实现克隆逻辑。DataTable.Clone无法执行此操作。