我知道我可以使用GetMethods
获取方法信息,但我想知道如何在没有GetMethods
的情况下正确执行此操作。我已经阅读了其他SO问题和答案,表明这是不可能的,或建议只使用LINQ,但这不是问题的答案。
从最基本的层面考虑一个静态泛型函数,它接受一个通用参数。
private static void Test<T>(T val)
{
}
要获取此方法信息,我们只需拨打Type.GetMethod("Test", BindingFlags.Static | BindingFlags.NonPublic)
即可。但是如果有一些原因我们无法使用这个简单的GetMethod
签名(可能是由于多次重载),那么我们需要提供参数类型。问题是我无法创建与T val
参数精确匹配的参数类型。有趣的是,我可以从方法信息中获取参数(使用GetMethods
获取)并将其传递到GetMethod
以获得所需的结果。这意味着如果只能创建适当的泛型类型(IsGenericParameter
设置为true),那么我觉得这是完全可能的。
这意味着这在.NET中是完全可能的,并且只需要创建正确的类型实例。如何创建这些类型实例?如果他们不可能创造,为什么他们不是?
我创建了a simple fiddle来展示问题。
答案 0 :(得分:5)
它不容易获得,因为您需要的类型实际上是方法/参数定义中仅存在的泛型类型参数。例如,在Test<T>(T val)
中,参数类型为&#34; T
由Test<T>
定义。您无法构建,因为它不是从组成的任何东西。获取T
的唯一方法是通过GetParameters()
。
基本上,它留下了:艰难的方式 - 即手动。例如:
var method1 = typeof(Program).GetMethods(flags).Single(x => x.Name == "Test"
&& x.IsGenericMethodDefinition && x.GetParameters().Length == 1
&& x.GetParameters()[0].ParameterType == x.GetGenericArguments()[0])
.MakeGenericMethod(paramTypes1);
如果您知道只有一种Test(...)
方法,显然会更简单:
var method = typeof(Program).GetMethod("Test", flags)
.MakeGenericMethod(paramTypes1);
答案 1 :(得分:2)
这不是调用GetMethod而是&#34;其他&#34;获得通用方法定义的方法是&#34; cast&#34;方法组到特定类型,然后在其上调用.Method.GetGenericDefinition()
。
在您的示例中,您需要的方法签名是Action<object>
,其中object只是一个占位符,可以是与泛型方法的约束匹配的任何类型。
var genericMethodDefinition =
((Action<object>)Test<object>).Method.GetGenericMethodDefinition();
你可以选择不同的重载&#34;测试&#34;通过使用以下内容定义为private static T Test<T>(T val, int counter)
。
var genericMethodDefinition2 =
((Func<object, int, object>)Test<object>).Method.GetGenericMethodDefinition();
答案 2 :(得分:1)
好吧,我不认为这是可能的。
但其他方法(仍然很难,我相信GetMethods
会更好):
var method1 =
typeof (Program).GetMember("Test*",
BindingFlags.InvokeMethod |
BindingFlags.NonPublic |
BindingFlags.Static)
.Cast<MethodInfo>()
.Single(
m =>
m.GetGenericArguments().Length == 1 &&
m.GetGenericArguments()[0].IsGenericParameter)
.MakeGenericMethod(paramTypes1);
当然,您可以省略MakeGenericMethod
以获得与method2
相同的结果。