在 C# 中通过反射获取扩展方法的泛型重载
Getting generic overload by reflection for extension method in C#
我有以下扩展程序class:
public static class KeyValueConfigurationCollectionExtensions
{
public static string Get(this KeyValueConfigurationCollection collection, string key)
{
return collection[key].Value;
}
public static T Get<T>(this KeyValueConfigurationCollection collection, string key)
{
return (T)Convert.ChangeType(collection[key].Value, typeof(T));
}
}
有人能告诉我如何通过反射获得泛型方法(上面示例中的第二个方法)的重载吗?这行代码在运行时抛出 AmbiguousMatchException
:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethod("Get");
我知道 GetMethod
函数有一个重载,我可以在其中指定参数,但在那种情况下,这两种方法的参数是相同的。解决这个问题会很棒,因为我需要它进行验收测试。
更新
对我来说最简单的解决方案是:
MethodInfo methodInfo = typeof(KeyValueConfigurationCollectionExtensions)
.GetMethods().Single(method => method.Name == "Get" && method.IsGenericMethod);
感谢大家的快速回答,祝你有美好的一天:)
您需要通过调用 GetGenericArguments() 来获取具有通用参数的方法,如本例中的 Linqpad:
void Main()
{
var method = typeof(KeyValueConfigurationCollectionExtensions)
.GetMethods()
.Where(m => m.Name == "Get")
.Where(m => m.GetGenericArguments().Any())
.Single()
.Dump();
}
// Define other methods and classes here
public static class KeyValueConfigurationCollectionExtensions
{
public static string Get(this KeyValueConfigurationCollection collection, string key)
{
return collection[key].Value;
}
public static T Get<T>(this KeyValueConfigurationCollection collection, string key)
{
return (T)Convert.ChangeType(collection[key].Value, typeof(T));
}
}
public class KeyValueConfigurationCollection
{
public KeyValuePair<string, string> this [string key]
{
get
{
return new KeyValuePair<string, string>("KEY: " + key, "VALUE: Hi!");
}
}
}
如果你有一个重载的方法,那么你必须使用带有 linq 的 GetMethods 方法:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethods().FirstOrDefault(m=>m.Name=="Get"&&m.ContainsGenericParameters==true).MakeGenericMethod(new Type[]{yourtype});
在 MethodInfo
上还定义了 IsGenericMethod
:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethods()
.FirstOrDefault(x => g.Name == "Get" && x.IsGenericMethod);
我有以下扩展程序class:
public static class KeyValueConfigurationCollectionExtensions
{
public static string Get(this KeyValueConfigurationCollection collection, string key)
{
return collection[key].Value;
}
public static T Get<T>(this KeyValueConfigurationCollection collection, string key)
{
return (T)Convert.ChangeType(collection[key].Value, typeof(T));
}
}
有人能告诉我如何通过反射获得泛型方法(上面示例中的第二个方法)的重载吗?这行代码在运行时抛出 AmbiguousMatchException
:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethod("Get");
我知道 GetMethod
函数有一个重载,我可以在其中指定参数,但在那种情况下,这两种方法的参数是相同的。解决这个问题会很棒,因为我需要它进行验收测试。
更新
对我来说最简单的解决方案是:
MethodInfo methodInfo = typeof(KeyValueConfigurationCollectionExtensions)
.GetMethods().Single(method => method.Name == "Get" && method.IsGenericMethod);
感谢大家的快速回答,祝你有美好的一天:)
您需要通过调用 GetGenericArguments() 来获取具有通用参数的方法,如本例中的 Linqpad:
void Main()
{
var method = typeof(KeyValueConfigurationCollectionExtensions)
.GetMethods()
.Where(m => m.Name == "Get")
.Where(m => m.GetGenericArguments().Any())
.Single()
.Dump();
}
// Define other methods and classes here
public static class KeyValueConfigurationCollectionExtensions
{
public static string Get(this KeyValueConfigurationCollection collection, string key)
{
return collection[key].Value;
}
public static T Get<T>(this KeyValueConfigurationCollection collection, string key)
{
return (T)Convert.ChangeType(collection[key].Value, typeof(T));
}
}
public class KeyValueConfigurationCollection
{
public KeyValuePair<string, string> this [string key]
{
get
{
return new KeyValuePair<string, string>("KEY: " + key, "VALUE: Hi!");
}
}
}
如果你有一个重载的方法,那么你必须使用带有 linq 的 GetMethods 方法:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethods().FirstOrDefault(m=>m.Name=="Get"&&m.ContainsGenericParameters==true).MakeGenericMethod(new Type[]{yourtype});
在 MethodInfo
上还定义了 IsGenericMethod
:
MethodInfo method = typeof(KeyValueConfigurationCollectionExtensions).GetMethods()
.FirstOrDefault(x => g.Name == "Get" && x.IsGenericMethod);