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.