我需要将一个类型列表传递给一个方法,但我想确保(在编译时)所有这些都继承自BaseType。 另外,我不知道必须传递多少种类型。
所以我认为这将是一个糟糕的方式:
public void DoSomething(params Type[] types)
所以我到目前为止所做的事情是这样的:
private void DoSomething(params Type[] types)
public void DoSomething<T1>()
where T1 : BaseType
{
DoSomething(typeof(T1));
}
public void DoSomething<T1, T2>()
where T1 : BaseType
where T2 : BaseType
{
DoSomething(typeof(T1), typeof(T2));
}
public void DoSomething<T1, T2, T3>()
where T1 : BaseType
where T2 : BaseType
where T3 : BaseType{...}
// and so on...
你明白了。 所以问题是:你能做得更漂亮吗? 因为这不支持任意数量的类型。 在我的场景中,八种或更多种类型并不太常见。
我想将此用作this类型的“魔法”,但调用者没有对容器的引用。
答案 0 :(得分:6)
没有办法在C#(或CIL)中表示这样的约束,所以你要么必须努力编写所有这些重载,要么放弃编译时的安全性而只是在运行时检查-time。
如果可能,另一种替代方法是编写可以使用示例的重载。这是否有用取决于域名,真的。
public void DoSomething(params BaseClass[] examples)
{
//null-checks here
Type[] types = examples.Select(e => e.GetType())
.ToArray();
//...
}
用法(假设BaseClass
为Mammal
):
// Compiles fine.
DoSomething(new Goat(), new Tiger(), new Lion());
// Won't compile.
DoSomething(new Fish(), new Tiger(), new Lion());
这是一个在运行时检查的示例:
public void DoSomething(Type[] types)
{
//null-checks here
// Or perhaps you want IsSubclassOf...
if(types.Any(t => !typeof(BaseClass).IsAssignableFrom(t))
throw new ArgumentException(...);
}
答案 1 :(得分:1)
不,泛型类型由命名空间,类名和类型参数的数量定义(即,在同一名称空间中,类型参数的数量相同,您不能拥有同名的类,甚至如果对它们的约束不同的话。)
如果单个类可能有一个未定义数量的类型参数,那么框架就可以利用Action&lt;&gt;和Func&lt;&gt;课程,它没有。