可以在编译时检查通用工厂函数的构造函数参数
本文关键字:函数 工厂 构造函数 参数 编译 检查 | 更新日期: 2023-09-27 18:19:20
我正在试验一些工厂类型代码,其中BuildIt函数仅基于传入的泛型类型返回具体类型。泛型类型被限制为BaseAbstract类的后代。
Buildit函数只需要泛型类型和一个参数列表(这些参数在创建具体类时用作Buildit函数的构造函数参数)。
下面的示例代码按预期工作(打印"A"然后"B")
但是如果我尝试调用像
这样的东西,问题就发生了: var b = fs.BuildIt<B>("B", "C");
由于B类没有带有两个参数的构造函数,因此在运行时失败。
有可能做这样的事情,除了在编译时失败吗?如果没有,是否有另一种方法可以使编译时检查成为可能(如果所有这些都必须抛出并开始完全不同的东西也没关系)
示例代码public abstract class BaseAbstract
{
public string Name ="";
public override string ToString ()
{
return Name;
}
}
public class A : BaseAbstract
{
public A()
{
Name = "A";
}
}
public class B : BaseAbstract
{
public B()
{
}
public B(string param)
{
Name = param;
}
}
public class Factory
{
public T BuildIt<T>(params object[] args) where T : BaseAbstract, new()
{
T x = (T)Activator.CreateInstance(typeof(T), args);
return x;
}
}
public class MainClass
{
public static void Main (string[] args)
{
//These are fine
Factory fs = new Factory();
var a = fs.BuildIt<A>();
var b = fs.BuildIt<B>("B");
Console.WriteLine (a);
Console.WriteLine (b);
//This would cause runtime error because of the "C" paramter
//var b2 = fs.BuildIt<B>("B", "C");
}
}
不是真的,因为你正在使用反射,这是一种运行时技术…编译器意识到无法创建实例的唯一方法是运行您的代码……至少在CAAS出现之前。
一种选择可能是采用不同的方法:在方法中对泛型类型强制使用new()约束(确保所有类型都有一个无参数构造函数),然后可能将构造函数参数映射为属性,而不是在类型上?如果你想要不变性,可能不太理想,但反射可以写私有类型等…
这几乎就是构建ArgumentException类的目的。