Überprüfen Sie, ob die Instanz von einem Typ ist

180

Verwenden Sie diese Option, um zu überprüfen, ob ces sich um eine Instanz von handelt TForm.

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

Gibt es einen typsichereren Weg, dies zu tun, stringals a als Parameter zu verwenden CompareTo()?

Lennie
quelle
20
Ich hoffe auf jeden Fall, dass Sie es auch in Java nicht so machen. Java instanceofund C # issind viel bessere Möglichkeiten, dies zu tun.
Powerlord

Antworten:

410

Die unterschiedlichen Antworten hier haben zwei unterschiedliche Bedeutungen.

Wenn Sie überprüfen möchten, ob eine Instanz von einem genauen Typ ist, dann

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

ist der Weg zu gehen.

Wenn Sie wissen möchten, ob ces sich um eine Instanz TForm oder eine Unterklasse handelt, verwenden Sie is/ as:

if (c is TForm)

oder

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

Es lohnt sich, sich klar darüber zu sein, welches dieser Verhaltensweisen Sie tatsächlich wollen.

Jon Skeet
quelle
7
Ein kleiner Hinweis: Verwenden Sie "ist", wenn Sie das Ergebnis der Besetzung nicht verwenden möchten, und verwenden Sie "als", wenn Sie dies tun.
Aviram Fireberger
14
Mit C # 7 können Sie kombinieren isund asmit Mustervergleich:if (x is TForm tf) {…
Richard
39
if(c is TFrom)
{
   // Do Stuff
}

oder wenn Sie cals verwenden möchten TForm, verwenden Sie das folgende Beispiel:

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

Das zweite Beispiel muss nur einmal überprüft werden, ob ces vom Typ ist TForm. Wenn Sie prüfen, ob ces sich um einen Typ handelt, und ihn TFormdann umsetzen , wird die CLR einer zusätzlichen Prüfung unterzogen. Hier ist eine Referenz .

Edit: Von Jon Skeet gestohlen

Wenn Sie sicherstellen möchten, dass ces sich um TFormeine Klasse handelt, von der keine erbt TForm, verwenden Sie

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

Auch etwas in die gleiche Richtung

Type.IsAssignableFrom(Type c)

"True, wenn c und der aktuelle Typ denselben Typ darstellen oder wenn sich der aktuelle Typ in der Vererbungshierarchie von c befindet oder wenn der aktuelle Typ eine von c implementierte Schnittstelle ist oder wenn c ein generischer Typparameter und der aktuelle Typ ist stellt eine der Einschränkungen von c dar. "

Von hier aus: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx

Brad Cunningham
quelle
das ist auch mein persönlicher Favorit. typeof(Class).IsAssignableFrom(object.getType())ähnlich dem Java- instanceofOperator.
SkidRunner
Gibt es false aus, wenn sie sich nicht im selben Zweig der Vererbungshierarchie befinden, aber ein Konvertierungsoperator vorhanden ist?
Paul Stelian
Gute Frage @PaulStelian. Ich bin mir nicht sicher, aber ich vermute, dass es in dieser Situation falsch sein würde. Das wäre zumindest mein erwartetes Verhalten. Wenn eine implizite Konvertierung vorhanden ist, gibt sie möglicherweise true zurück, aber das wäre seltsam.
Brad Cunningham
Wer hat Visual Studio installiert, um es zu versuchen?
Paul Stelian
1
@PaulStelian - es wird false zurückgegeben. Dies können Sie sehen, indem Sie dem Dokumentlink folgen und feststellen, dass keine Conversions erwähnt werden. Eine weitere Möglichkeit , darüber nachzudenken ist , dass die T1.IsAssignableFrom(T2)Renditen truein Situationen , in denen die asBetreiber liefert einen Wert ungleich Null, da Instanzen dieser Typen.
ToolmakerSteve
9

Etwas kompakter als die anderen Antworten, wenn Sie c als TForm verwenden möchten:

if(c is TForm form){
    form.DoStuff();
}
Ali Rahman
quelle
3

Versuche Folgendes

if (c is TForm) { 
 ...
}
JaredPar
quelle
2

Wie andere bereits erwähnt haben, ist das Schlüsselwort "is". Wenn Sie es jedoch später in diesen Typ umwandeln möchten, z.

TForm t = (TForm)c;

Dann sollten Sie das Schlüsselwort "as" verwenden.

z.B TForm t = c as TForm.

Dann können Sie überprüfen

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

Nicht so kombinieren wie mit, da es sich um eine doppelte Prüfung handelt.

taylonr
quelle
0

Oder

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

oder einfacher

bool isValid = c.GetType() == typeof(TForm);
Gabe
quelle
IMHO: Ich würde ein direktes Mitgefühl vermeiden (dh ==). In objekt- oder orientierten Sprachen, die die Vererbung unterstützen, es sei denn, Sie wissen, dass Ihr spezifischer Typ niemals von beispielsweise einer sealedKlasse geerbt wird . Außerdem: Die Verwendung eines ternären Operators, der (statische / konstante) boolesche Werte zurückgibt, stört mich. Es würde mich weniger stören, wenn es sich um eine switchAnweisung handeln würde.
SkidRunner