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


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.


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
}


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


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();
}


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.



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

oder einfacher

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.