检查某个类型是否为Action委托

时间:2011-03-01 03:56:00

标签: c# reflection delegates

无论参数数量多少,我都在尝试检查给定类型是否为动作委托。

以下代码是我知道如何执行此操作的唯一方法。

    public static bool IsActionDelegate( this Type source )
    {
        return source == typeof( Action ) ||
               source.IsOfGenericType( typeof( Action<> ) ) ||
               source.IsOfGenericType( typeof( Action<,> ) ) ||
               ....
               source.IsOfGenericType( typeof( Action<,,,,,,,,,,,,,,,> ) );
    }

IsOfGenericType()是我的另一种扩展方法,它执行它所说的,它检查类型是否属于给定的泛型类型。

有更好的建议吗?

4 个答案:

答案 0 :(得分:5)

如果您只是在具有void返回类型的代理之后,您可以执行以下操作:

public static bool IsActionDelegate(Type sourceType)
{
    if(sourceType.IsSubclassOf(typeof(MulticastDelegate)) && 
       sourceType.GetMethod("Invoke").ReturnType == typeof(void))
        return true;
    return false;
}

但是,这不会区分ActionMethodInvoker(或其他无效代表)。正如其他答案建议你可以检查类型名称,但有点气味;-) 如果你能澄清你想要识别Action代表的原因,那将会有所帮助,看看哪种方法最有效。

答案 1 :(得分:4)

    static Type[] _actionTypes = new[]{
        typeof(Action),
        typeof(Action<>),
        typeof(Action<,>),
        typeof(Action<,,>),
        typeof(Action<,,,>),
        typeof(Action<,,,,>),
        typeof(Action<,,,,,>),
        typeof(Action<,,,,,,>),
        typeof(Action<,,,,,,,>),
        typeof(Action<,,,,,,,,>),
        typeof(Action<,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,,,,,>),
        typeof(Action<,,,,,,,,,,,,,,,>)
    };
    private static bool IsAction(Delegate d)
    {
        return d != null && Array.IndexOf(_actionTypes, d.GetType()) != -1;
    }

答案 2 :(得分:2)

这似乎有效:

    private static bool IsActionDelegate(this Type source)
    {
        var type = source.Name;
        return source.Name.StartsWith("System.Action");
    }

示例:

public static class Test
{
    public static bool IsActionDelegate(this Type source)
    {
        var type = source.Name;
        return source.Name.StartsWith("Action");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Action<string> one = s => { return; };
        Action<int, string> two = (i, s) => { return; };
        Func<int, string> function = (i) => { return null; };

        var single = one.GetType().IsActionDelegate();
        var dueces = two.GetType().IsActionDelegate();
        var func = function.GetType().IsActionDelegate();
    }
}

Single和deuces是真的。 func是假的

答案 3 :(得分:2)

这些是不同的类型,没有任何共同点,但它们的名称。我能想到的唯一半合理的捷径:

public static bool IsActionDelegate( this Type source )
{
    return source.FullName.StartsWith("System.Action");
}

当然不是故障安全的,但是在System命名空间中声明自己的类型的人应该有一些痛苦和痛苦。

相关问题