我希望获得一个使用反射接受Action<T>
参数的方法定义。我使用.NET核心1.1。
由于该类有两个同名的方法,我试图检查接受参数的类型,以确保我得到正确的方法定义(而不是其他重载),但这种比较似乎不起作用。
以下是一些显示此问题的代码:
using System;
using System.Linq;
using System.Reflection;
class ReflectMe {
public void SomeMethod<T>(Action<T> action) {
action(default(T));
}
public T SomeMethod<T>() {
return default(T);
}
}
class Program {
static void Main(string[] args) {
var reflectedMethod = typeof(ReflectMe).GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => m.Name == "SomeMethod" && m.IsGenericMethodDefinition)
.Where(m => {
var parameters = m.GetParameters();
if (parameters.Count() != 1) {
// this filters out the 1st method
return false;
}
var actionType = typeof(Action<>);
var parameterType = parameters[0].ParameterType;
if (parameterType == actionType) {
// this is always false, even if in the debugger both
// types are displayed as System.Action`1[T]
return true;
}
return false;
})
.FirstOrDefault();
}
}
问题是parameterType
和actionType
不相等,但是当我检入调试器时,它们看起来完全相同。
为什么这种比较失败?
答案 0 :(得分:8)
您需要实例化Action<T>
的泛型定义以使用该方法的泛型参数:
var methodTypeArg = m.GetGenericArguments().First();
var actionType = typeof(Action<>).MakeGenericType(methodTypeArg);
注意:我现在没有.NET Core 1.1,我希望api是一样的,但是你的问题在任何.NET版本中都是一样的。
如果将泛型参数的名称更改为方法,则需要调用MakeGenericType
的原因变得更加明显:
public void SomeMethod<TMethodArg>(Action<TMethodArg> action)
然后typeof(Action<>) != typeof(Action<TMethod>)
变得更加明显。您正在比较Action<>
的通用定义(它位于T
上)与泛型方法TMethod
的泛型参数(SomeMethod
)的定义实例化/ p>