有没有一种方法可以获得Func<;T、 bool>;
本文关键字:lt Func gt bool 一种 方法 有没有 | 更新日期: 2023-09-27 18:16:44
短版本:
我们可以使用获得Func<T,T>
的类型
typeof(Func<,>)
但是,如果我想获得Func<T, bool>
的类型,我应该使用什么,或者可以这样做吗?显然这并不能编译:
typeof(Func<, bool>)
长版本:
考虑以下场景,我有两个类似的方法,我想使用反射获得第二个方法(Func<T, int>
(:
public void Foo<T>(Func<T, bool> func) { }
public void Foo<T>(Func<T, int> func) { }
我正在尝试这个:
var methodFoo = typeof (Program)
.GetMethods()
.FirstOrDefault(m => m.Name == "Foo" &&
m.GetParameters()[0]
.ParameterType
.GetGenericTypeDefinition() == typeof (Func<,>));
但由于Func<T, bool>
和Func<T, int>
的泛型类型定义是相等的,所以它给了我第一种方法。要解决这个问题,我可以做以下操作:
var methodFoo = typeof (Program)
.GetMethods()
.FirstOrDefault(m => m.Name == "Foo" &&
m.GetParameters()[0]
.ParameterType
.GetGenericArguments()[1] == typeof(int));
然后我得到了正确的方法,但我不喜欢这种方式。对于更复杂的情况来说,这似乎是一种开销。我想做的是像上面失败的尝试中那样获得Func<T,bool>
的类型,然后我可以使用GetMethod
的过载,而不是使用Linq,并执行以下操作:
var methodFoo = typeof (Program)
.GetMethod("Foo",
BindingFlags.Public | BindingFlags.Instance,
null,
new[] {typeof (Func<, bool>)}, // ERROR typeof(Func<,>) doesn't work either
null);
注意:当然Func<T,T>
只是一个例子,问题并不是特定于任何类型的。
很遗憾,您无法为部分绑定的泛型类型构建System.Type
对象。你做这件事的方式(即使用GetGenericArguments()[1] == typeof(int)
(是正确的方式
如果您需要在多个地方重复使用它,您可以构建一个助手扩展方法,该方法采用泛型类型定义和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, int>
的类型,所以它肯定是在的某个地方构建的
上面的类型T
是泛型方法Foo
的泛型类型参数。由于它不是"任何类型",如果你愿意,你可以构造这种类型:
var typeT = methodFoo.GetGenericArguments()[0];
var funcTbool = typeof(Func<,>).MakeGenericType(typeT, typeof(bool));
问题是typeT
绑定到特定的泛型方法,使得funcTbool
类型不适合在多个独立的泛型方法之间进行搜索。
如果T
是该方法所属类的类型参数,比如
class FooType<T> {
public void Foo(Func<T, bool> func) { }
public void Foo(Func<T, int> func) { }
}
您将能够基于FooType<>
的泛型类型参数构造funcTbool
,并在不同Foo(...)
方法的签名中搜索它。