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()?

Lennie
la source
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.

Jon Skeet
la source
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
}
Facteur
la source
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

Brad Cunningham
la source
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();
}
Ali Rahman
la source
3

Essayez ce qui suit

if (c is TForm) { 
 ...
}
JaredPar
la source
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.

taylonr
la source
0

Ou

c.getType() == typeOf(TForm)
Raynos
la source
-1
bool isValid = c.GetType() == typeof(TForm) ? true : false;

ou plus simple

bool isValid = c.GetType() == typeof(TForm);
Gabe
la source
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