So überprüfen Sie, ob der Variablentyp mit dem in einer Variablen gespeicherten Typ übereinstimmt


96
User u = new User();
Type t = typeof(User);

u is User -> returns true

u is t -> compilation error

Wie teste ich auf diese Weise, ob eine Variable von einem Typ ist?

Antworten:


194

Die anderen Antworten enthalten alle signifikante Auslassungen.

Der isOperator prüft nicht , ob der Laufzeittyp des Operanden genau dem angegebenen Typ entspricht. Stattdessen wird geprüft, ob der Laufzeittyp mit dem angegebenen Typ kompatibel ist :

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

Die Überprüfung der Typidentität mit Reflection prüft jedoch die Identität und nicht die Kompatibilität

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an 

Wenn Sie das nicht möchten, möchten Sie wahrscheinlich IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A 

4
Während der hier gezeigte endgültige Ansatz funktioniert, ist er unnötig ausführlich. typeof(Animal).IsInstanceOfType(x)ist kürzer und unkomplizierter als typeof(Animal).IsAssignableFrom(x.GetType());(und Resharper schlägt vor, das erstere zu verwenden, wenn Sie das letztere verwenden).
Mark Amery

ERKLÄRUNG: die ursprüngliche Frage zu beantworten, Ersatz tfür typeof(Animal). So wird Marks verbesserte Form t.IsInstanceOfType(x).
ToolmakerSteve

13

GetType()existiert für jeden einzelnen Framework-Typ, da er für den Basistyp definiert ist object. Unabhängig vom Typ selbst können Sie damit den Basiswert zurückgebenType

Alles was Sie tun müssen ist:

u.GetType() == t

1
Eigentlich ist Erics Antwort hilfreich und alles, beantwortet aber nicht die eigentliche Frage, wie man mit einem unbekannten Typ auf die in der ursprünglichen Frage beschriebene "u is t" -Methode testet, und Ihre auch.
Daniel

@ Daniel - Nicht genau. Daves Antwort ist nur richtig, wenn Sie Unterklassen von t ausschließen möchten . Erics Antwort erklärt hauptsächlich, was zu tun ist; es fehlt nur die Klarstellung, wo "t" zu setzen ist. Ich werde dort einen Kommentar hinzufügen.
ToolmakerSteve

10

Sie müssen überprüfen, ob der Typ Ihrer Instanz dem Typ der Klasse entspricht. Um den Instanztyp abzurufen, verwenden Sie die folgende GetType()Methode:

 u.GetType().Equals(t);

oder

 u.GetType.Equals(typeof(User));

Sollte es tun. Natürlich können Sie '==' verwenden, um Ihren Vergleich durchzuführen, wenn Sie dies bevorzugen.


+1 Aber lieber die zweite Wahl. u.GetType.Equals(typeof(User));
Omar

Ein Grund, warum dies weniger sicher ist als die Verwendung von == - ist, dass wenn GetType () irgendwie null zurückgibt, es wirft.
Dave Bish

1
@Fuex, ja ich, ich denke, es erleichtert das Lesen des Codes, wenn der Typ inline ist, weshalb ich ihn so gepostet habe, obwohl er im OPs-Beispiel bereits eine Variable hat, tdie den Typ enthält.
Sam Holder

@ DaveBish, wenn GetType null zurückgibt, dann würde ich mir Sorgen machen, dass viele Dinge anfangen würden zu werfen ... aber Punkt genommen, Sie haben natürlich Recht
Sam Holder

@SamHolder Ja - Die einzige Situation, in der dies passieren würde, wäre, wenn jemand einen Basistyp überschreibt und die Implementierung irgendwie vermasselt. Es wäre sicher komisch.
Dave Bish

4

Um zu überprüfen, ob ein Objekt mit einer bestimmten Typvariablen kompatibel ist, anstatt zu schreiben

u is t

du solltest schreiben

typeof(t).IsInstanceOfType(u)

1
Was ist der Vorteil der ausführlicheren Syntax gegenüber der Syntax 'u is t'?
Kyle Humfeld

@KyleHumfeld Wenn Sie Typ foo hatten; Objekt A; Sie können nicht "A is foo" schreiben, aber Sie können foo.isInstanceOfType (A)
Timur Nuriyasov
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.