Vérifier si l'instance est d'un type


181

Utiliser ceci pour vérifier si cest une instance de TForm.

c.GetType().Name.CompareTo("TForm") == 0

Existe-t-il un moyen plus sûr de le faire en plus d'utiliser un stringcomme paramètre CompareTo()?


20
J'espère certainement que vous ne le faites pas non plus en Java de cette façon. Java instanceofet C # issont de bien meilleurs moyens de le faire.
Powerlord

Réponses:


410

Les différentes réponses ici ont deux significations différentes.

Si vous souhaitez vérifier si une instance est d' un type exact, alors

if (c.GetType() == typeof(TForm))

est la voie à suivre.

Si vous voulez savoir s'il cs'agit d'une instance TForm ou d'une sous-classe, utilisez is/ as:

if (c is TForm)

ou

TForm form = c as TForm;
if (form != null)

Cela vaut la peine d'être clair dans votre esprit pour savoir lequel de ces comportements vous voulez réellement.


7
Une petite note: utilisez "est" si vous ne voulez pas utiliser le résultat de la distribution et utilisez "comme" si vous le faites.
Aviram Fireberger

14
Avec C # 7, vous pouvez combiner iset asavec la correspondance de motifs:if (x is TForm tf) {…
Richard

39
if(c is TFrom)
{
   // Do Stuff
}

ou si vous prévoyez d'utiliser en ctant que TForm, utilisez l'exemple suivant:

var tForm = c as TForm;
if(tForm != null)
{
   // c is of type TForm
}

Le deuxième exemple n'a besoin de vérifier si cest de type TFormqu'une seule fois. Où est si vous vérifiez si voir si cest de type TFormpuis le cast, le CLR subit une vérification supplémentaire. Voici une référence .

Edit: volé à Jon Skeet

Si vous voulez vous assurer que cc'est de TFormet non une classe héritant de TForm, alors utilisez

if(c.GetType() == typeof(TForm))
{
   // Do stuff cause c is of type TForm and nothing else
}


10

Aussi, un peu dans la même veine

Type.IsAssignableFrom(Type c)

"Vrai si c et le Type actuel représentent le même type, ou si le Type actuel est dans la hiérarchie d'héritage de c, ou si le Type actuel est une interface que c implémente, ou si c est un paramètre de type générique et le Type actuel représente l'une des contraintes de c. "

De là: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx


c'est aussi mon préféré. typeof(Class).IsAssignableFrom(object.getType())similaire à l' instanceofopérateur Java .
SkidRunner

Donne-t-il false s'ils ne sont pas dans la même branche de la hiérarchie d'héritage mais qu'un opérateur de conversion existe?
Paul Stelian

Bonne question @PaulStelian. Je ne suis pas sûr du haut de ma tête, mais je suppose que cela renverrait un faux dans cette situation. Ce serait au moins mon comportement attendu. Peut-être que si une conversion implicite existe, elle pourrait retourner true mais ce serait étrange.
Brad Cunningham

Quiconque a installé Visual Studio pour l'essayer?
Paul Stelian

1
@PaulStelian - il renvoie faux. Cela peut être vu en suivant le lien doc, et en observant qu'il n'y a aucune mention de conversions. Une autre façon de penser est que T1.IsAssignableFrom(T2)retourne truedans les situations où l' asopérateur renvoie une valeur non nulle, étant donné les instances de ces types.
ToolmakerSteve

9

Un peu plus compact que les autres réponses si vous souhaitez utiliser c comme TForm:

if(c is TForm form){
    form.DoStuff();
}


2

Comme d'autres l'ont mentionné, le mot-clé «est». Cependant, si vous allez le convertir plus tard dans ce type, par exemple.

TForm t = (TForm)c;

Ensuite, vous devez utiliser le mot-clé "as".

par exemple TForm t = c as TForm.

Ensuite, vous pouvez vérifier

if(t != null)
{
 // put TForm specific stuff here
}

Ne combinez pas comme c'est parce que c'est une vérification en double.



-1
bool isValid = c.GetType() == typeof(TForm) ? true : false;

ou plus simple

bool isValid = c.GetType() == typeof(TForm);

IMHO: J'éviterais une compassion directe (ie. ==). Dans les langages objets ou orientés prenant en charge l'héritage, sauf si vous savez que votre type spécifique ne sera jamais hérité d'une sealedclasse par exemple . Aussi: l'utilisation d'un opérateur ternaire renvoyant des valeurs booléennes (statiques / constantes) me dérange, je serais moins gêné si c'était une switchinstruction.
SkidRunner
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.