C# 有没有办法获得typeof Func<;T、 bool>;?

C# 有没有办法获得typeof Func<;T、 bool>;?,c#,generics,reflection,C#,Generics,Reflection,短版: 我们可以使用以下方法获得Func的类型: typeof(Func<,>) 然后我得到了正确的方法,但我不喜欢这种方式。对于更复杂的情况来说,这似乎是一种开销。我想做的是像上面失败的尝试一样获取Func的类型,然后我可以使用GetMethod执行以下操作,而不是使用Linq: var methodFoo = typeof (Program) .GetMethods() .FirstOrDefault(m => m.Nam

短版:

我们可以使用以下方法获得
Func
的类型:

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

var methodFoo = typeof (Program)
            .GetMethods()
            .FirstOrDefault(m => m.Name == "Foo" &&
                        m.GetParameters()[0]
                        .ParameterType
                        .GetGenericArguments()[1] == typeof(int));
var methodFoo = typeof (Program)
            .GetMethod("Foo", 
            BindingFlags.Public | BindingFlags.Instance,
            null, 
            new[] {typeof (Func<, bool>)}, // ERROR typeof(Func<,>) doesn't work either
            null);
var methodFoo=typeof(程序)
.GetMethod(“Foo”,
BindingFlags.Public | BindingFlags.Instance,
无效的
new[]{typeof(Func)},//ERROR typeof(Func)也不起作用
无效);

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

不幸的是,您无法为部分绑定的泛型类型构建
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))
    );
问题是
typeT
绑定到特定的泛型方法,使得
funcTbool
类型不适合跨多个独立的泛型方法进行搜索

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

class FooType<T> {
    public void Foo(Func<T, bool> func) { }
    public void Foo(Func<T, int> func) { }
}
class-FooType{
公共无效Foo(Func Func){}
公共无效Foo(Func Func){}
}

您可以基于
FooType
的泛型类型参数构造
funcTbool
,并在不同
Foo(…)
方法的签名中搜索它。

+1个好问题!我们需要乔恩·斯基特的时候他在哪里?哈如果我使用
methodFoo.GetParameters()[0].ParameterType
,我得到的是
Func
的类型,所以它肯定是在某处构造的。。我想可能是可以直接得到它。@Selman22这是一个公平的观察-看看编辑。
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))
    );
var typeT = methodFoo.GetGenericArguments()[0];
var funcTbool = typeof(Func<,>).MakeGenericType(typeT, typeof(bool));
class FooType<T> {
    public void Foo(Func<T, bool> func) { }
    public void Foo(Func<T, int> func) { }
}