328 votes

En C#, comment vérifier si un type est un sous-type OU le type d'un objet ?

Pour vérifier si un type est une sous-classe d'un autre type en C#, c'est facile :

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true

Cependant, cela échouera :

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false

Existe-t-il un moyen de vérifier si un type est soit une sous-classe, soit la classe de base elle-même, sans utiliser une fonction OR opérateur ou en utilisant une méthode d'extension ?

486voto

Lasse V. Karlsen Points 148037

Apparemment, non.

Voici les options :

Type.IsSubclassOf

Comme vous l'avez déjà constaté, cela ne fonctionnera pas si les deux types sont identiques, voici un échantillon LINQPad qui démontre :

void Main()
{
    typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
    typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}

public class Base { }
public class Derived : Base { }

Sortie :

True
False

Ce qui indique que Derived est une sous-classe de Base mais que Base n'est (évidemment) pas une sous-classe d'elle-même.

Type.IsAssignableFrom

Cela répondra à votre question particulière, mais vous obtiendrez également des faux positifs. Comme Eric Lippert l'a souligné dans les commentaires, alors que la méthode renverra effectivement True pour les deux questions ci-dessus, il retournera également True pour ces derniers, ce que vous ne voulez probablement pas :

void Main()
{
    typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
    typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
    typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}

public class Base { }
public class Derived : Base { }

Vous obtenez le résultat suivant :

True
True
True

La dernière True il indiquerait, si la méthode uniquement a répondu à la question posée, que uint[] hérite de int[] ou qu'ils sont du même type, ce qui n'est clairement pas le cas.

Así que IsAssignableFrom n'est pas non plus tout à fait correct.

is y as

Le "problème" avec is y as dans le contexte de votre question, c'est qu'ils vous demanderont d'opérer sur les objets et d'écrire l'un des types directement dans le code, et non de travailler avec des Type objets.

En d'autres termes, ça ne compilera pas :

SubClass is BaseClass
^--+---^
   |
   +-- need object reference here

et ceci non plus :

typeof(SubClass) is typeof(BaseClass)
                    ^-------+-------^
                            |
                            +-- need type name here, not Type object

et ceci non plus :

typeof(SubClass) is BaseClass
^------+-------^
       |
       +-- this returns a Type object, And "System.Type" does not
           inherit from BaseClass

Conclusion

Bien que les méthodes ci-dessus puissent répondre à vos besoins, la seule réponse correcte à votre question (telle que je la vois) est que vous aurez besoin d'un contrôle supplémentaire :

typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);

ce qui, bien entendu, est plus logique dans une méthode :

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase)
           || potentialDescendant == potentialBase;
}

35voto

Marc Gravell Points 482669
typeof(BaseClass).IsAssignableFrom(unknownType);

11voto

Thomas Points 42973

Vous devriez essayer d'utiliser Type.IsAssignableFrom à la place.

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