有没有办法让typeof运算函数功能< T,BOOL&GT ;? [英] Is there a way to get typeof Func<T, bool>?

查看:122
本文介绍了有没有办法让typeof运算函数功能< T,BOOL&GT ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短版:



我们可以得到的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<> 的泛型类型参数,并在不同的的签名进行搜索美孚(...)方法

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> and Func<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 of GetMethod 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. with GetGenericArguments()[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 returns true 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 of Func<T, int> so it is definitely being constructed somewhere

The type T above is the generic type parameter of your generic method Foo. 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 the funcTbool type not suitable for searching across multiple independent generic methods.

If T were a type argument of the class to which the method belongs, say

class 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 on FooType<>'s generic type parameter, and search for it in the signatures of the different Foo(...) methods.

这篇关于有没有办法让typeof运算函数功能&LT; T,BOOL&GT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆