332 votes

Vérifiez si une classe est dérivée d'une classe générique

J'ai une classe générique dans mon projet avec des classes dérivées.

public class GenericClass : GenericInterface
{
}

public class Test : GenericClass
{
}

Existe-t-il un moyen de savoir si un objet de type Type est dérivé de GenericClass ?

t.IsSubclassOf(typeof(GenericClass<>))

ne fonctionne pas.

0voto

isandburn Points 116

En retard par rapport à ça... moi aussi j'ai une autre permutation de la réponse de JarodPar.

voici Type.IsSubClassOf(Type) gracieuseté de reflector:

    public virtual bool IsSubclassOf(Type c)
    {
        Type baseType = this;
        if (!(baseType == c))
        {
            while (baseType != null)
            {
                if (baseType == c)
                {
                    return true;
                }
                baseType = baseType.BaseType;
            }
            return false;
        }
        return false;
    }

à partir de cela, nous voyons que cela ne fait rien de trop fou et est similaire à l'approche itérative de JaredPar. jusqu'ici, tout va bien. voici ma version (avertissement : non testée en profondeur, donc dites-moi si vous trouvez des problèmes)

    public static bool IsExtension(this Type thisType, Type potentialSuperType)
    {
        //
        // protégez-vous
        //
        if (thisType == null || potentialSuperType == null || thisType == potentialSuperType) return false;

        //
        // pas besoin de parcourir l'héritage pour l'extension de l'interface, donc vérifiez/faites ces vérifications d'abord
        //
        if (potentialSuperType.IsInterface)
        {
            foreach (var interfaceType in thisType.GetInterfaces())
            {
                var tempType = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;

                if (tempType == potentialSuperType)
                {
                    return true;
                }
            }
        }

        //
        // effectuez les vérifications de type concret, en itérant sur la chaîne d'héritage, comme dans l'original
        //
        while (thisType != null && thisType != typeof(object))
        {
            var cur = thisType.IsGenericType ? thisType.GetGenericTypeDefinition() : thisType;

            if (potentialSuperType == cur)
            {
                return true;
            }

            thisType = thisType.BaseType;
        }
        return false;
    }

essentiellement, il s'agit simplement d'une méthode d'extension à System.Type - j'ai fait cela pour limiter intentionnellement le "thisType" Type aux Types concrets, car mon utilisation immédiate est de faire des requêtes LINQ "where" contre des objets de Type. je suis sûr que tous les intelligents parmi vous pourraient le transformer en une méthode statique efficace et polyvalente si vous en avez besoin :) le code fait quelques choses que le code de la réponse ne fait pas

  1. l'ouvre à une "extension" générale - je considère l'héritage (pensez aux classes) ainsi que l'implémentation (interfaces); les noms des méthodes et des paramètres sont changés pour mieux refléter cela
  2. validation de null en entrée (meh)
  3. entrée du même type (une classe ne peut pas étendre elle-même)
  4. exécution en circuit-courte si le Type en question est une interface; car GetInterfaces() retourne toutes les interfaces implémentées (même celles implémentées dans les super-classes), vous pouvez simplement parcourir cette collection sans avoir à grimper dans l'arbre d'héritage

le reste est essentiellement le même que le code de JaredPar

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X