有没有办法获得类型Func ?

精简版 :

我们可以使用以下方法获取func Func

 typeof(Func) 

但是如果我想获得Func的类型,我应该使用什么,或者它可以做什么呢? 显然,这不编译:

 typeof(Func) 

长版:

考虑以下场景,我有两个类似的方法,我想使用Reflection得到第二个( Func ):

 public void Foo(Func func) { } public void Foo(Func func) { } 

我正在尝试这个:

  var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .GetGenericTypeDefinition() == typeof (Func)); 

但由于FuncFunc的generics类型定义相等,它给出了第一种方法。 要解决这个问题,我可以执行以下操作:

 var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .GetGenericArguments()[1] == typeof(int)); 

然后我得到了正确的方法,但我不喜欢这种方式。 对于更复杂的情况,这似乎是一种开销。 我想要做的是获取Func的类型,就像我上面的失败尝试一样,然后使用Linq而不是使用Linq我可以使用GetMethod 这个重载并执行如下操作:

 var methodFoo = typeof (Program) .GetMethod("Foo", BindingFlags.Public | BindingFlags.Instance, null, new[] {typeof (Func)}, // ERROR typeof(Func) doesn't work either null); 

注意:Ofcourse Func只是一个例子,问题不是特定于任何类型。

不幸的是,您无法为部分绑定的generics类型构建System.Type对象。 你这样做的方式(即使用GetGenericArguments()[1] == typeof(int) )是正确的方法。

如果需要在多个位置重用它,可以构建一个辅助扩展方法,该方法接受generics类型定义和System.Type对象数组,如果匹配则返回true

 static bool IsGenericInstance(this Type t, Type genTypeDef, params Type[] args) { if (!t.IsGenericType) return false; if (t.GetGenericTypeDefinition() != genTypeDef) return false; var typeArgs = t.GetGenericArguments(); if (typeArgs.Length != args.Length) return false; // Go through the arguments passed in, interpret nulls as "any type" for (int i = 0 ; i != args.Length ; i++) { if (args[i] == null) continue; if (args[i] != typeArgs[i]) return false; } return true; } 

现在您可以像这样重写代码:

 var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .IsGenericInstance(typeof(Func<,>), null, typeof(bool)) ); 

如果我使用methodFoo.GetParameters()[0].ParameterType ,我得到的类型为Func所以它肯定是在某处构建的

上面的类型T是generics方法Foo的generics类型参数。 由于它不是“任何类型”,如果您愿意,可以构造此类型:

 var typeT = methodFoo.GetGenericArguments()[0]; var funcTbool = typeof(Func<,>).MakeGenericType(typeT, typeof(bool)); 

问题是typeT绑定到特定的generics方法,使得funcTbool类型不适合搜索多个独立的generics方法。

如果T是该方法所属类的类型参数,请说

 class FooType { public void Foo(Func func) { } public void Foo(Func func) { } } 

你可以根据FooType<>的generics类型参数构造一个funcTbool ,并在不同的Foo(...)方法的签名中搜索它。