7
votes

Vérifier si un certain type est un délégué d'action

J'essaie de vérifier si un type donné est un délégué d'action, indépendamment de la quantité de paramètres.

Le code suivant est le seul moyen de savoir comment faire cela. P>

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


0 commentaires

4 Réponses :


2
votes

Ceci semble fonctionner:

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


2 commentaires

J'ai pensé à vérifier le nom avant, mais j'espérais qu'il y avait une solution plus propre / plus sûre.


Oui, cela semblait évident. J'étais juste curieux de cela, c'est pourquoi je l'ai écrit. Je ne pense pas qu'il y ait quelque chose de sécurité lorsque vous êtes en train de gêner avec des types indépendants et de les traiter comme équivalent.



2
votes

Ce sont des types distincts sans rien en commun mais leur nom. Le seul raccourci semi-raisonnable que je puisse penser:

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


0 commentaires

7
votes

Si vous êtes juste après que les délégués disposent d'un type de retour indéfini, vous pouvez effectuer ce qui suit:

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


3 commentaires

Je ne sais pas si la recherche par nom est tout ce mal étant donné que le nom vient d'un espace de noms de bibliothèque et non de code d'utilisateur.


Grande perspicacité, merci! J'essaie de faire une méthode générique de délégué.createdélégate. Par exemple. Createdelegate > (propriétaire, méthode); C'est un travail en cours, donc je ne sais pas encore si cela sera possible. Mais c'est pourquoi j'ai besoin d'analyser le paramètre générique et de vérifier quel type de délégué est attendu.


@ Ritch - Cela me rappelle de vérifier le type de navigateur en JavaScript au lieu d'une vérification des fonctionnalités - la plus tardive est beaucoup plus propre. Peut-être injustifié dans ce cas, mais je ne toucherais pas le nom si je n'avais absolument pas besoin.



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

1 commentaires

Techniquement, le code doit être Array.indexof (_ActionTypes, D.getType (). GetGenerictypeDefinition ())! = - 1.