有没有办法让typeof运算函数功能< T,BOOL> ;? [英] Is there a way to get typeof Func<T, bool>?
问题描述
短版:
我们可以得到的typeof Func键< T,T>
使用:
的typeof(Func键<,>)
但如果我想获得 Func键< T,BOOL>
,我应该怎么用,或者是有可能这样做?显然,这不能编译:
的typeof(Func键< ;,布尔>)
龙版本:
考虑以下情形,我有两个类似的方法,我想获得第二个( Func键< T,INT>
)使用反射:
公共无效美孚< T>(Func键< T,BOOL> FUNC){}
公共无效美孚< T> (Func键< T,INT> FUNC){}
我想这样的:
VAR methodFoo = typeof运算(程序)
.GetMethods()
.FirstOrDefault(M = GT; m.Name ==富与功放;&安培;
m.GetParameters()[0]
.ParameterType
.GetGenericTypeDefinition()== typeof运算(Func键<,>));
不过,由于 Func键1所述的泛型类型定义; T,BOOL>
和 Func键< T,INT>
等于它给我的第一个方法。为了解决这个问题,我可以做到以下几点:
VAR methodFoo = typeof运算(程序)
.GetMethods()
.FirstOrDefault(M = GT; m.Name ==富与功放;&安培;
m.GetParameters()[0]
.ParameterType
.GetGenericArguments()[1] == typeof运算(INT));
然后我得到了正确的方法,但我不喜欢这种方式。而现在似乎为更复杂的情况下,一个开销。我想要做的就是的类型Func键< T,BOOL>
就像在我失败的尝试上面的话,而不是使用LINQ我可以使用的 GetMethod
>和做类似如下:
VAR methodFoo = typeof运算(程序)
.GetMethod(富,
BindingFlags.Public | BindingFlags.Instance,
空,
新的[] {typeof运算(Func键< ;,布尔>)} //错误的typeof(Func键<,>)无法正常工作或
NULL);
请注意:Ofcourse Func键< T,T>
只是一个例子,问题是不特定于任何类型的。
不幸的是,你不能建立一个的System.Type
对象部分的约束泛型类型。你做的方式(即 GetGenericArguments()[1] == typeof运算(INT)
)是这样做的正确方法。
如果您需要重新使用在多个地方,你可以建立,需要一个泛型类型定义和数组的帮助扩展方法的System.Type
对象,并返回真正
如果有匹配的:
静态布尔IsGenericInstance(这种类型T,类型genTypeDef,则params类型[]参数){
如果返回false(t.IsGenericType!);
如果(t.GetGenericTypeDefinition()= genTypeDef!)返回false;
VAR typeArgs = t.GetGenericArguments();
如果(!typeArgs.Length = args.Length)返回false;
//穿过的参数去,空解释为任何类型的
的for(int i = 0; i = args.Length;!我++){
如果(参数[我] == NULL)继续;
如果(参数[I] = typeArgs [I]!)返回false;
}
返回真;
}
现在你可以重写你这样的代码:
VAR methodFoo = typeof运算(程序)
.GetMethods()
.FirstOrDefault(M = GT; m.Name ==富&放大器;&安培;
m.GetParameters()[0]
.ParameterType
.IsGenericInstance(typeof运算(Func键<,>),空的typeof(布尔))
);
如果我用
methodFoo.GetParameters() [0] .ParameterType
,我得到的类型Func键< T,INT>
所以它肯定是正在建设中的某处
块引用>
的键入
T
上面是你的泛型方法的泛型类型参数富
。既然不是任何类型,你可以,如果你想建立这种类型的:VAR typeT = methodFoo.GetGenericArguments() [0];
VAR funcTbool = typeof运算(Func键<,>)MakeGenericType(typeT的typeof(布尔))。
美中不足的是,
typeT
势必会具体的泛型方法,使得funcTbool
键入不适合跨多个独立的通用方法搜索。
如果
T
是哪个方法属于类的类型参数,比如类FooType< T> {
公共无效美孚(Func键< T,BOOL> FUNC){}
公共无效美孚(Func键< T,INT> FUNC){}
}
您将能够构建一个
funcTbool
根据FooType<>
的泛型类型参数,并在不同的的签名进行搜索美孚(...)
方法。 p>Short version :
We can get the typeof
Func<T,T>
using:typeof(Func<,>)
but what if I want to get the type of
Func<T, bool>
, what should I use, or is it possible to do? Clearly this doesn't compile :typeof(Func<, bool>)
Long version :
Consider the following scenario, I have two similar method and I want to get the second one (
Func<T, int>
) using Reflection:public void Foo<T>(Func<T, bool> func) { } public void Foo<T>(Func<T, int> func) { }
I'm trying this:
var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .GetGenericTypeDefinition() == typeof (Func<,>));
But since the generic type definition of
Func<T, bool>
andFunc<T, int>
are equal it gives me the first method. To fix this I can do the following:var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .GetGenericArguments()[1] == typeof(int));
Then I get the correct method but I do not like this way. And it seems like a overhead for more complex situations. What I want to do is get the type of
Func<T,bool>
like in my failed attempt above, then instead of using Linq I can use this overload ofGetMethod
and do something like the following:var methodFoo = typeof (Program) .GetMethod("Foo", BindingFlags.Public | BindingFlags.Instance, null, new[] {typeof (Func<, bool>)}, // ERROR typeof(Func<,>) doesn't work either null);
Note: Ofcourse
Func<T,T>
is just an example, question is not specific to any type.解决方案Unfortunately, you cannot build a
System.Type
object for a partially bound generic type. The way that you do it (i.e. withGetGenericArguments()[1] == typeof(int)
) is the proper way of doing it.If you need to re-use this in multiple places, you could build a helper extension method that takes a generic type definition and an array of
System.Type
objects, and returnstrue
if there is a match: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; }
Now you can rewrite your code like this:
var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Name == "Foo" && m.GetParameters()[0] .ParameterType .IsGenericInstance(typeof(Func<,>), null, typeof(bool)) );
if I use
methodFoo.GetParameters()[0].ParameterType
, I'm getting the type ofFunc<T, int>
so it is definitely being constructed somewhereThe type
T
above is the generic type parameter of your generic methodFoo
. Since it is not "any type", you could construct this type if you wish:var typeT = methodFoo.GetGenericArguments()[0]; var funcTbool = typeof(Func<,>).MakeGenericType(typeT, typeof(bool));
The catch is that
typeT
is bound to the specific generic method, making thefuncTbool
type not suitable for searching across multiple independent generic methods.If
T
were a type argument of the class to which the method belongs, sayclass FooType<T> { public void Foo(Func<T, bool> func) { } public void Foo(Func<T, int> func) { } }
you would be able to construct a
funcTbool
based onFooType<>
's generic type parameter, and search for it in the signatures of the differentFoo(...)
methods.这篇关于有没有办法让typeof运算函数功能< T,BOOL> ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!