C#中任意数量的类型参数 [英] Arbitrary number of type parameters in C#

查看:131
本文介绍了C#中任意数量的类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将一个List类型传递给一个方法,但我想确定(在编译时),它们都是从BaseType继承的。
另外,我不知道有多少个类型必须被传递。



所以我认为这将是一个不好的方法:

  public void DoSomething(params Type [] types)

所以我到现在为止所做的是这样的:

  private void DoSomething(params类型[]类型)

public void DoSomething< T1>()
其中T1:BaseType
{
DoSomething(typeof(T1));
}

public void DoSomething< T1,T2>()
其中T1:BaseType
其中T2:BaseType
{
DoSomething typeof(T1),typeof(T2));


$ b public void DoSomething< T1,T2,T3>()
其中T1:BaseType
其中T2:BaseType
其中T3:BaseType {...}

//等等...



你有想法。
所以问题是:你可以做得更漂亮吗?
因为这不支持任意数量的类型。
在我的情况下,八种或更多类型不会太少见。



我想用这个来表示这个类,但调用者没有对容器的引用。



如果可能的话,另一种方法是编写一个可以利用示例的重载。是否真的有用取决于域名。

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

Type [] types = examples.Select(e => e.GetType())
.ToArray();
// ...
}

用法(比方说 BaseClass 哺乳动物):

  //编译好。 
DoSomething(新的Goat(),新的Tiger(),新的Lion());

//不会编译。
DoSomething(new Fish(),new Tiger(),new Lion());

以下是运行时检查的示例:

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

//或者你想要IsSubclassOf ...
if(types.Any(t =>!typeof(BaseClass).IsAssignableFrom(t))
throw new ArgumentException(...);
}


I need to pass a List of Types to a method, but I want to be sure (at compile time that is) that all of them inherit from BaseType. Also, I dont know how many Types have to be passed.

So I figured this would be a bad way to go:

public void DoSomething(params Type[] types)

So what I ended up doing up to now is something like this:

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...

You get the Idea. So the Question is: can you do this a bit more beautifully? Because this does not support an arbitrary number of types. And in my scenario, eight or more types would not be too uncommon.

I want to use this for "magic" of this kind but the caller does not have a reference to the container.

解决方案

There's no way to represent such a constraint in C# (or CIL for that matter), so you're going to either have to struggle through with writing all those overloads, or give up compile-time safety and just check at run-time.

If possible, one other alternative would be to write an overload that can make use of examples. Whether or not this would be useful depends on the domain, really.

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

   Type[] types = examples.Select(e => e.GetType())
                          .ToArray();
   //...    
}

Usage (let's say the BaseClass was Mammal):

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

// Won't compile.
DoSomething(new Fish(), new Tiger(), new Lion()); 

And here's a sample for checking at run-time:

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

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

这篇关于C#中任意数量的类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆