Проверка, является ли определенный тип делегатом Action - PullRequest
7 голосов
/ 01 марта 2011

Я пытаюсь проверить, является ли данный тип делегатом действия, независимо от количества параметров.

Следующий код - единственный способ узнать, как это сделать.

    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 ]

5 голосов
/ 01 марта 2011

Если вы находитесь сразу после делегатов, имеющих тип возврата void, вы можете сделать следующее:

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

Это не будет проводить различия между Action и MethodInvoker (или другими недействительными делегатами в этом отношении). Как показывают другие ответы, вы можете изучить имя типа, но это отчасти пахнет ;-) Было бы полезно, если бы вы могли уточнить, по какой причине вы хотите идентифицировать Action делегатов, чтобы увидеть, какой подход будет работать лучше всего.

4 голосов
/ 01 марта 2011
    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 голосов
/ 01 марта 2011

Это разные типы, которые не имеют ничего общего, кроме их названия.Единственный разумный ярлык, который я могу придумать:

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

Конечно, небезопасен, но тот, кто объявляет свои собственные типы в пространстве имен System, заслуживает некоторой боли и страданий.

2 голосов
/ 01 марта 2011

Это похоже на работу:

    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 и должное правда. func = false

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...