Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 制作具有多种类型的泛型_C#_Generics - Fatal编程技术网

C# 制作具有多种类型的泛型

C# 制作具有多种类型的泛型,c#,generics,C#,Generics,我有一段代码,有时我需要创建一个新的泛型类型,但泛型参数的数量未知。例如: public object MakeGenericAction(Type[] types) { return typeof(Action<>).MakeGenericType(paramTypes); } 公共对象MakeGenericAction(类型[]类型) { 返回typeof(Action).MakeGenericType(paramTypes); } 问题是,如果数组中有多个类型,那么程序

我有一段代码,有时我需要创建一个新的泛型类型,但泛型参数的数量未知。例如:

public object MakeGenericAction(Type[] types)
{
  return typeof(Action<>).MakeGenericType(paramTypes);
}
公共对象MakeGenericAction(类型[]类型)
{
返回typeof(Action).MakeGenericType(paramTypes);
}
问题是,如果数组中有多个类型,那么程序将崩溃。在短期内,我想出了类似这样的办法作为权宜之计

public object MakeGenericAction(Type[] types)
{
  if (types.Length == 1)
  {
    return typeof(Action<>).MakeGenericType(paramTypes);
  }
  else if (types.Length ==2)
  {
    return typeof(Action<,>).MakeGenericType(paramTypes);
  }
  ..... And so on....
}
公共对象MakeGenericAction(类型[]类型)
{
if(types.Length==1)
{
返回typeof(Action).MakeGenericType(paramTypes);
}
else if(types.Length==2)
{
返回typeof(Action).MakeGenericType(paramTypes);
}
等等
}
这确实有效,并且很容易涵盖我的场景,但它似乎真的很粗糙。有没有更好的方法来处理这个问题?

在这种情况下,是的:

Type actionType = Expression.GetActionType(types);
不过,这里的问题是,您可能会使用速度较慢的DynamicVoke


一个
操作
然后按索引访问可能比一个用DynamicInvoke调用的
操作
更出色,更优雅的解决方案(或者至少是反射泛型)非常好。如果数组中的类型超过16种,会发生什么情况?除了密码警察从你身上拿走所有的电子设备。@IndigoDelta齿轮会掉出来;普芬塔斯蒂克!我自己永远也不会发现这一点。我应该指出,里面也有一个“GetFuncType”。@Marc:说得好。此外,构建框架这一部分的构建脚本会自动检查是否添加了新的操作类型,并适当地重新生成代码,因此我们有理由相信,即使将来添加更多的操作类型,这也会继续产生良好的结果!
Assembly asm = typeof(Action<>).Assembly;
Dictionary<int, Type> actions = new Dictionary<int, Type>;
foreach (Type action in asm.GetTypes())
    if (action.Name == "Action" && action.IsGenericType)
        actions.Add(action.GetGenericArguments().Lenght, action)
public Type MakeGenericAction(Type[] types)
{
  return actions[types.Lenght].MakeGenericType(paramTypes);
}