如何检查MethodInfo是否匹配泛型类型T的委托,其中T是Action还是Func?

时间:2015-02-05 21:01:11

标签: c# generics reflection delegates

问题:如何检查MethodInfo匹配Delegate类型的T,其中TAction或{ {1}}?

代码示例,其中包含从Func获取所有静态函数的用例 } {/ 1}} {/ 1}}

Assembly

函数调用示例:

Delegate

注意:不将T括在try / catch块中。

1 个答案:

答案 0 :(得分:3)

您应该通过检查参数和返回类型来手动检查签名是否兼容。

例如,以下代码检查方法与委托的分配兼容性。这并不会将类型限制为ActionFunc;它适用于任何委托类型。

private void AddScriptFunctions<T>(Assembly assembly, Dictionary<string, T> funMap) where T : class
{
    foreach (Type type in assembly.GetTypes())
    {
        var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
        foreach (MethodInfo method in methods)
        {
            if (IsMethodCompatibleWithDelegate<T>(method)))
            {
                var function = (T) (object) Delegate.CreateDelegate(typeof (T), method);
                funMap.Add(method.Name.ToLower(), function);
            }
        }
    }
}

public bool IsMethodCompatibleWithDelegate<T>(MethodInfo method) where T : class
{
    Type delegateType = typeof(T);
    MethodInfo delegateSignature = delegateType.GetMethod("Invoke");

    bool parametersEqual = delegateSignature
        .GetParameters()
        .Select(x => x.ParameterType)
        .SequenceEqual(method.GetParameters()
            .Select(x => x.ParameterType));

    return delegateSignature.ReturnType == method.ReturnType &&
           parametersEqual;
}

当然这段代码并没有考虑到逆差;如果你需要反复工作,你需要检查参数是否兼容,而不仅仅是等于(就像我一样)。

遵循防御性编程习惯,您可能需要验证类型参数T以检查它是否真的是委托类型。我把它留给你。