Dot-Net

如何在非泛型 .NET 類型上獲取泛型方法的 MethodInfo?

  • April 7, 2016

我有這個小問題,我無法弄清楚要傳遞給 Type.GetMethod 的參數,以便在非泛型類型上取回泛型方法的 MethodInfo。具體來說,我有這個類型定義:

public static class A
{
 public static B F<T>(bool dummy)
 {
 }
 public static B F<T>(IEnumerable<T> arg)
 {
 ...
 }
}

我在 Type.GetMethod 上嘗試了幾次,但沒有一個會返回 F 方法的 MethodInfo。

我知道我可以呼叫 Type.GetMethods 甚至 Type.FindMember,但我對 Type.GetMethod 很感興趣。

有任何想法嗎?

謝謝。

編輯

實際上,我的程式碼有點複雜。泛型方法被重載,所以我不能只使用函式名來使用 Type.GetMethod。我嘗試了這些變體:

typeof(A).GetMethod("F", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F`1", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F[T]", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F[[T]]", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)

問題是IEnumerable<>您傳遞給的參數GetMethod不是專門的。它確實是一個IEnumerable<T>,T由您嘗試檢索的方法指定。但是,我們無法T通過,MethodInfo.GetGenericArguments()因為我們沒有對該方法的引用——我們仍在嘗試檢索它。

不幸的是,這就是反射 API 的不足之處。沒有Type.GetMethod()重載可以讓您區分重載方法,其中一個是泛型方法。

因此,話雖如此,您仍然無法使用Type.GetMethods()您選擇的謂詞來使用和過濾結果。要獲得您感興趣的方法,您可以執行以下操作。

void getMethod()
{
   typeof(A).GetMethods().Where(m =>
       m.IsGenericMethod &&
       m.GetParameters()[0].ParameterType.GetGenericTypeDefinition()
           == typeof(IEnumerable<>));
}

注意我還沒有驗證GetGenericTypeDefinition()是否需要呼叫;你可以省略它。這個想法是您正在將類型A<T>轉換為A<>,但執行時可能已經以這種形式將其提供給您。

引用自:https://stackoverflow.com/questions/1624817