从派生类的类型初始化器传递并注册一个工厂委托,然后你就完成了工作:
public abstract class BaseClass {
static readonly Dictionary<Type, Delegate>
m_factories = new Dictionary<Type, Delegate> { };
public static BaseClass CreateInstance(DataTable dataTable) {
var type = typeof(Child1);
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
return (Child1)m_factories[type].DynamicInvoke(dataTable);
}
public static BaseClass CreateInstance(DataSet dataSet) {
var type = typeof(Child2);
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
return (Child2)m_factories[type].DynamicInvoke(dataSet);
}
protected static void AddFactory<TArgs, T>(Func<TArgs, T> factory) {
m_factories.Add(typeof(T), factory);
}
}
public class Child1:BaseClass {
Child1(DataTable dataTable) {
}
static Child1() {
BaseClass.AddFactory((DataTable dt) => new Child1(dt));
}
}
public class Child2:BaseClass {
Child2(DataSet dataSet) {
}
static Child2() {
BaseClass.AddFactory((DataSet ds) => new Child2(ds));
}
}
public static class TestClass {
public static void TestMethod() {
var child2 = BaseClass.CreateInstance(new DataSet { });
var child1 = BaseClass.CreateInstance(new DataTable { });
}
}
如果所有派生类都直接从基类继承,那么您不必担心注册冲突——没有主体可以访问另一个类的构造函数。
因为您可能希望将它声明TArgs
为Func<TArgs, T>
可变参数泛型参数,尽管它不是 C♯ 的一个特性,但它Tuple
是模拟它的方法之一。有关此主题的更多信息,您可能需要查看:
在 C# 中模拟可变参数模板