根据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);
}
答案 0 :(得分:1)
当克隆System.Data.DataTable时,它会调用受保护的DataTable成员CreateInstance,该成员最终使用Activator类来构造基础DataTable类型。
protected virtual DataTable CreateInstance()
{
return (DataTable) Activator.CreateInstance(base.GetType(), true);
}
GetType将返回MyDataTable的实际Type引用。请记住,即使您在基类中调用GetType,它也会返回MyDataTable的实际实例类型。另外,作为注释,Activator类是一种基于类型数据构建新对象的简单方法,无需手动使用反射来查找ConstructorInfo以创建对象的新实例。
您可以在MSDN
上找到有关Activator课程的更多信息查看这些类型问题的绝佳方案是Reflector(它是免费的!)。 Reflector允许您查看任何装配的内部,以查看实际发生的情况。
答案 1 :(得分:1)
如果您使用Reflector挖掘DataTable的代码,您将遇到此方法,由私有Clone(DataSet)方法调用:
protected virtual DataTable CreateInstance()
{
return (DataTable) Activator.CreateInstance(base.GetType(), true);
}
换句话说,它会创建一个类的新实例,而不是DataTable。请注意,此克隆将具有典型DataTable属性的深层副本,但您可能已添加但未在构造函数中指定的任何字段将具有其默认值。