C#中任意数量的类型参数

bla*_*dog 6 c# generics

我需要将一个类型列表传递给一个方法,但我想确保(在编译时)所有这些都继承自BaseType.另外,我不知道必须传递多少种类型.

所以我认为这将是一个糟糕的方式:

public void DoSomething(params Type[] types)
Run Code Online (Sandbox Code Playgroud)

所以到目前为止我最终做的是这样的:

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...
Run Code Online (Sandbox Code Playgroud)

你明白了.所以问题是:你能做得更漂亮吗? 因为这不支持任意数量的类型.在我的场景中,八种或更多种类型并不太常见.

我想用这个"神奇" 这个样,但调用者没有在容器上的参考.

Ani*_*Ani 6

没有办法在C#(或CIL)中表示这样的约束,所以你要么必须努力编写所有那些重载,要么放弃编译时的安全性,只需在运行时检查.

如果可能,另一种替代方法是编写可以使用示例的重载.这是否有用取决于域名,真的.

public void DoSomething(params BaseClass[] examples)
{
    //null-checks here

   Type[] types = examples.Select(e => e.GetType())
                          .ToArray();
   //...    
}
Run Code Online (Sandbox Code Playgroud)

用法(让我们说BaseClassMammal):

// Compiles fine.
DoSomething(new Goat(), new Tiger(), new Lion());

// Won't compile.
DoSomething(new Fish(), new Tiger(), new Lion()); 
Run Code Online (Sandbox Code Playgroud)

这是一个在运行时检查的示例:

public void DoSomething(Type[] types)
{
    //null-checks here

    // Or perhaps you want IsSubclassOf...
   if(types.Any(t => !typeof(BaseClass).IsAssignableFrom(t))
        throw new ArgumentException(...);           
}
Run Code Online (Sandbox Code Playgroud)