【问题标题】:Why is GetMethods() of a parameterized generic interface returning a non-parameterized MethodInfo为什么参数化泛型接口的 GetMethods() 返回非参数化 MethodInfo
【发布时间】:2014-05-05 17:11:21
【问题描述】:

鉴于这些接口:

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

根据 Microsoft 的 documentation,这不是 GetMethods() 的正确行为:

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

不幸的是,当涉及到类型解析的泛型接口时,情况似乎并非如此。

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

【问题讨论】:

  • 请从IGenericBase&lt;T&gt;.MyMethod 中删除或重命名通用方法规范。我不认为您打算在接口和方法中复制相同的类型参数名称(编译器会为此创建警告)。

标签: c# .net generics reflection interface


【解决方案1】:

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);
}

【讨论】:

  • 可能会忽略类型名称 T 已重新定义的编译器警告。如果该方法被声明为MyMethod&lt;U&gt;,那么它将按预期工作。
  • 哇,很好,这应该是显而易见的。谢谢!史蒂夫,你的警告是对的。
猜你喜欢
  • 2014-08-23
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多