Steven Jeuris
Steven Jeuris

Reputation: 19100

Checking whether a certain type is an Action delegate

I'm trying to check whether a given type is an action delegate, regardless of the amount of parameters.

The following code is the only way I know how to do this.

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

IsOfGenericType() is another extension method of mine, which does what it says, it checks whether the type is of the given generic type.

Any better suggestions?

Upvotes: 7

Views: 3064

Answers (4)

Double Down
Double Down

Reputation: 908

    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;
    }

Upvotes: 4

BrokenGlass
BrokenGlass

Reputation: 160922

If you are just after the delegates that have a void return type you could do the following:

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

This would not distinguish between Action and MethodInvoker (or other void delegates for that matter) though. As other answers suggest you could examine the type name, but that kinda smells ;-) It would help if you could clarify for what reason you want to identify Action delegates, to see which approach would work best.

Upvotes: 7

Hans Passant
Hans Passant

Reputation: 941635

These are distinct types with nothing in common but their name. The only semi-reasonable shortcut I can think of:

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

Certainly not fail-safe, but whomever declares his own types in the System namespace deserves some pain and suffering.

Upvotes: 2

Ritch Melton
Ritch Melton

Reputation: 11608

This seems to work:

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

Example:

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 and dueces are true. func is false

Upvotes: 2

Related Questions