Controlla se l'istanza è di un tipo


181

Usando questo per verificare se cè un'istanza di TForm.

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

Esiste un modo più sicuro per farlo oltre a usare a stringcome parametro per CompareTo()?


20
Spero sicuramente che tu non lo faccia nemmeno in Java in quel modo. Java instanceofe C # issono modi molto migliori per farlo.
Powerlord,

Risposte:


410

Le diverse risposte qui hanno due significati diversi.

Se vuoi verificare se un'istanza è di un tipo esatto allora

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

è la strada da percorrere.

Se vuoi sapere se cè un'istanza TForm o una sottoclasse, usa is/ as:

if (c is TForm)

o

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

Vale la pena di essere chiaro nella mente su quale di questi comportamenti si desidera effettivamente.


7
Una piccola nota: usa "è" se non vuoi usare il risultato del cast e usa "come" se lo fai.
Aviram Fireberger,

14
Con C # 7 puoi combinare ise abbinare i aspattern:if (x is TForm tf) {…
Richard

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

o se prevedi di utilizzarlo ccome a TForm, usa il seguente esempio:

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

Il secondo esempio deve solo verificare se cè di tipo TFormuna volta. Ovunque se controlli se vedi se cè di tipo, TFormquindi esegui il cast, il CLR viene sottoposto a un controllo aggiuntivo. Ecco un riferimento .

Modifica: rubato da Jon Skeet

Se vuoi assicurarti di cappartenere TForme non di alcuna classe che eredita TForm, allora usa

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


10

Inoltre, un po 'nella stessa vena

Type.IsAssignableFrom(Type c)

"Vero se c e il Tipo corrente rappresentano lo stesso tipo, o se il Tipo corrente è nella gerarchia di ereditarietà di c, o se il Tipo corrente è un'interfaccia che c implementa, o se c è un parametro di tipo generico e il Tipo corrente rappresenta uno dei vincoli di c. "

Da qui: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx


questo è anche il mio preferito. typeof(Class).IsAssignableFrom(object.getType())simile instanceofall'operatore Java .
SkidRunner

Dà falso se non si trovano nello stesso ramo della gerarchia ereditaria ma esiste un operatore di conversione?
Paul Stelian,

Bella domanda @PaulStelian. Non sono sicuro dalla parte superiore della mia testa ma la mia ipotesi sarebbe che restituirebbe un falso in quella situazione. Questo sarebbe almeno il mio comportamento previsto. Forse se esiste una conversione implicita, potrebbe tornare vero ma sarebbe strano.
Brad Cunningham,

Chiunque abbia installato Visual Studio per provarlo?
Paul Stelian,

1
@PaulStelian - restituisce false. Questo può essere visto seguendo il link doc e osservando che non si fa menzione delle conversioni. Un altro modo di pensarci è che T1.IsAssignableFrom(T2)ritorna truein situazioni in cui l' asoperatore restituisce un valore non nullo, date le istanze di quei tipi.
ToolmakerSteve

9

Un po 'più compatto rispetto alle altre risposte se si desidera utilizzare c come TForm:

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


2

Come altri hanno già detto, la parola chiave "è". Tuttavia, se in seguito lo proverai su quel tipo, ad es.

TForm t = (TForm)c;

Quindi dovresti usare la parola chiave "as".

per esempio TForm t = c as TForm.

Quindi puoi controllare

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

Non combinare come è perché è un controllo duplicato.



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

o più semplice

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

IMHO: Eviterei una compassione diretta (cioè. ==). In linguaggi oggetto o orientati che supportano l'ereditarietà a meno che non si sappia che il proprio Tipo specifico non verrà mai ereditato da una sealedClasse. Inoltre: l'uso di un operatore ternario che restituisce valori booleani (statici / costanti) mi dà fastidio, sarei meno infastidito se fosse switchun'affermazione.
SkidRunner
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.