通用方法与运行时类型

问题描述:

这是奇怪,但源代码通用方法与运行时类型

public class Processor<T> where T: class 
{ 
... 
    private object WorkWithSubtype(IRequester nextRequester, Type type) 
    { 
     if (type.GetInterface("IList") != null) 
     { 
      var originalType = type.GetGenericArguments()[0]; 
      var list = Activator.CreateInstance(type); 

      var method = typeof(Processor<>).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType); 
      var resList = method.Invoke(this, new object[] { nextRequester }); 
      typeof(List<>).GetMethod("AddRange").MakeGenericMethod(originalType).Invoke(list, new object[] { resList }); 
      return list; 
     } 
    } 

    private IEnumerable<K> GetObjects<K>(IRequester requester) where K: class 
    { 
     ... 
     //We can call method WorkWithSubtype in this method sometimes 
    } 
} 

执行和我“晚绑定操作不能在类型或其中ContainsGenericParameters是正确的方法来进行。”抛出异常是在'var resList = method.Invoke(this,new object [] {nextRequester});'。你可以帮我吗?提前致谢!

您有两个通用参数:一个是处理器类;另一个是GetObjects方法。在创建泛型方法时,您为方法的类型参数提供了一个类型参数,但是您尚未为该类的泛型参数提供类型参数。

根据处理器类的目的,你可以尝试以下解决方案之一:

  • 构建封闭泛型类型与类型参数
  • 使用typeof(Processor<T>)而不是使用反射来构建关闭通用类型
  • 从类
  • 移除类型参数从所述方法除去的类型参数

我认为第二个最有可能是你在找什么:

var method = typeof(Processor<T>) 
    .GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance) 
    .MakeGenericMethod(originalType); 

此外,AddRange不是一个通用的方法;相反,List<>是一个泛型类型,所以:

typeof(List<>) 
    .MakeGenericType(originalType) 
    .GetMethod("AddRange") 
    .Invoke(list, new object[] { resList }); 
+0

谢谢,你是对的,我很愚蠢。我需要typeof(Processot )。再次感谢。 – Udgin 2012-04-16 20:15:42

您需要使用MakeGenericType像这样:

var method = typeof(Processor<>).MakeGenericType(typeof(T)).GetMethod("GetObjects", BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(originalType); 

同样,当你调用AddRange方法。

问题是List<string>.AddRange是与List<int>.AddRange不同的方法,MakeGenericType将类型参数应用于类。调用MakeGenericMethod对于GetObjects仍然是必需的,因为它具有与包含类(T)不同的泛型类型参数(K)。