有没有办法获得类型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));
但由于Func
和Func
的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(...)
方法的签名中搜索它。