[英]How do you get specific generic method overload from static class using reflection?
所以我有一個 static class:
class static EnumHelper {
public string GetCode<E>(E value) where E: struct {}
public string GetCode<E>(E? value) where E: struct {}
}
但是使用:
typeof(EnumHelper).GetMethod("GetCode")
總是返回這個錯誤:
System.Reflection.AmbiguousMatchException:找到不明確的匹配項。
但是,我不能直接使用提供“參數類型”的 GetMethod 的重載,因為參數類型基於方法本身中定義的泛型類型參數。
目標是:
//given parameter: T item
MethodInfo mi = typeof(EnumHelper).GetMehod("GetCode");
mi.MakeGenericMethod(typeof(T));
mi.Invoke(null, new object[] {item});
但我在這個等式的“GetMethod”部分遇到了麻煩。
謝謝。
最終,您將需要手動消除它們之間的歧義,也許通過使用Nullable.GetUnderlyingType
並測試它是否是null
或not null
,在它們之間進行選擇。 例如,查找E value
版本:
var method = typeof(EnumHelper).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(method => method.Name == nameof(EnumHelper.GetCode)
&& Nullable.GetUnderlyingType(method.GetParameters().Single().ParameterType) is null);
相同但is not null
給你E?
版本。
EnumHelper
有兩個同名的不同方法,因此“默認” GetMethod
無法在它們之間進行選擇。 您需要手動找出T
的可空性和所需的方法。
根據您使用的框架版本,您可以對所有方法執行過濾:
var type = typeof(T);
var sourceTypeNullable = Nullable.GetUnderlyingType(type) != null;
var mi = typeof(EnumHelper)
.GetMethods()
.Where(mi => mi.Name == "GetCode")
.Where(mi => mi.GetParameters() == 1)
.Where(mi => sourceTypeNullable == (Nullable.GetUnderlyingType(mi.GetParameters()[0].ParameterType) != null))
.Single();
var constructed = mi.MakeGenericMethod(Nullable.GetUnderlyingType(type) ?? type);
constructed.Invoke(...);
或使用Type.MakeGenericMethodParameter
(自 .NET Core 2.1 起可用),它允許構建通用參數描述符並將其傳遞給GetMethod
重載,接受表示搜索方法參數的Type
對象集合:
var genericType = Type.MakeGenericMethodParameter(0);
genericType = sourceTypeNullable
? Type.MakeGenericSignatureType(typeof(Nullable<>), genericType) // or typeof(Nullable<>).MakeGenericType(genericType) for pre 3.0 versions
: genericType;
var mi = typeof(EnumHelper).GetMethod(nameof(EnumHelper.GetCode), new[] {genericType});
constructed = mi.MakeGenericMethod(Nullable.GetUnderlyingType(type) ?? type);
您可以根據參數的類型和類型參數是否相同,select 一個或另一個:
var mi = (from m in typeof(EnumHelper).GetMethods()
where m.Name == "GetCode"
let targ = m.GetGenericArguments()[0]
let param = m.GetParameters()[0].ParameterType
where targ != param // and == for the non-nullable version
select m).Single();
Type tArg = typeof(ConsoleColor);
var value = ConsoleColor.Black;
mi.MakeGenericMethod(tArg).Invoke(null, new object[] {value});
另請參閱此處的實時示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.