代码之家  ›  专栏  ›  技术社区  ›  Daniel James Bryars

派生System.Data.DataTable时,DataTable.Clone如何返回派生类?

  •  0
  • Daniel James Bryars  · 技术社区  · 14 年前

    根据 http://msdn.microsoft.com/en-us/library/system.data.datatable.clone.aspx “如果这些类已派生,则克隆也将属于相同的派生类。”。

    在下面的示例代码中,基类上的clone方法如何“知道”创建派生类?

    public class MyDataTable : System.Data.DataTable
            {
                public override System.Data.DataTable Clone()
                {
                    //How is this a MyDataTable not a "DataTable" ?
                    return base.Clone();
                }
            }
    
            static void Main(string[] args)
            {
                MyDataTable dt = new MyDataTable();
                System.Diagnostics.Debug.Assert(dt.Clone() is MyDataTable);
            }
    
    2 回复  |  直到 14 年前
        1
  •  1
  •   Hans Passant    14 年前

    如果使用Reflector挖掘DataTable的代码,您将遇到此方法,该方法由private Clone(DataSet)方法调用:

    protected virtual DataTable CreateInstance()
    {
        return (DataTable) Activator.CreateInstance(base.GetType(), true);
    }
    

    换句话说,它创建类的新实例,而不是DataTable。请注意,此克隆将具有典型数据表属性的深层副本,但您可能已添加但未在构造函数中分配的任何字段都将具有其默认值。

        2
  •  1
  •   Chris Baxter    14 年前

    克隆System.Data.DataTable时,它调用最终使用Activator类构造基础数据表类型的受保护数据表成员CreateInstance。

    protected virtual DataTable CreateInstance()
    {
        return (DataTable) Activator.CreateInstance(base.GetType(), true);
    }
    

    其中GetType将返回对MyDataTable的实际类型引用。请记住,即使在基类中调用GetType,它也将返回MyDataTable的实际实例类型。同样值得注意的是,Activator类是一种基于类型数据构造新对象的简化方法,无需手动使用反射来查找ConstructorInfo以创建对象的新实例。

    您可以在 MSDN

    一个很好的程序来处理这些类型的问题是 Reflector (免费的!).Reflector允许您查看任何程序集的内部,以查看实际发生的情况。

    推荐文章