为什么参数化通用接口的GetMethods()返回非参数化的MethodInfo

时间:2014-03-26 23:57:11

标签: c# .net generics reflection interface

鉴于这些接口:

public interface IGenericBase<T>
{
    T MyMethod<T>(T arg1);
}

public interface IGenericDescendant : IGenericBase<int>
{
}

使用IGenericDescendant的类型,我通过GetInterfaces()获得接口集。正如预期的那样,它返回一个“已解析”(参数化)类型:IGenericBase`1,T解析为Int32。然后我在所述接口类型上调用GetMethods,期望得到一个类似解析的MyMethod版本,但我得到了通用版本,其中T作为未解析的类型参数。

var type = typeof(IGenericDescendant);    
foreach (var super in type.GetInterfaces())
{
    foreach (var member in super.GetMethods())
    {
        yield return member;  // Get MyMethod<T> not MyMethod<Int32>
    }
}

根据微软的documentation,这对GetMethods()来说不是正确的行为:

  

如果当前T:System.Type表示构造的泛型类型,   此方法返回带有类型参数的MethodInfo对象   由适当的类型参数替换

不幸的是,当谈到类型解析的通用接口时,情况似乎并非如此。

作为一种解决方法,我可以使用MakeGenericType()来解析类型参数,但是我必须知道类型,这意味着我必须通过遍历直到通过名称来解析类型参数层次结构。对于这个具体的例子来说这很容易,但我需要一个通用的解决方案。当然,我错过了一些明显的东西。

1 个答案:

答案 0 :(得分:3)

MyMethod是泛型接口中声明的泛型方法。如果为泛型类型指定参数,它仍然是一种通用方法。例如:

IGenericDescendant x = new SomeImplementation();
x.MyMethod<string>("abc"); // method is still generic

IGenericBase<int> y = new SomeOtherImplementation();
y.MyMethod<string>("abc"); // still can do that

您可能希望将接口声明为

public interface IGenericBase<T>
{
    T MyMethod(T arg1);
}