Jak sprawdzić, czy typ zmiennej pasuje do Typu przechowywanego w zmiennej


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

u is User -> returns true

u is t -> compilation error

Jak sprawdzić, czy jakaś zmienna jest tego typu?

Odpowiedzi:


197

Pozostałe odpowiedzi zawierają istotne pominięcia.

isOperator ma nie sprawdzić, czy rodzaj runtime argumentu jest dokładnie dany typ; raczej sprawdza, czy typ środowiska wykonawczego jest zgodny z danym typem:

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.

Ale sprawdzanie tożsamości typu z odbiciami sprawdza tożsamość , a nie zgodność

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 

Jeśli nie tego chcesz, prawdopodobnie chcesz 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
Chociaż pokazane tutaj końcowe podejście działa, jest niepotrzebnie rozwlekłe. typeof(Animal).IsInstanceOfType(x)jest krótszy i prostszy niż typeof(Animal).IsAssignableFrom(x.GetType());(a Resharper zasugeruje użycie pierwszego, jeśli użyjesz drugiego).
Mark Amery,

Wyjaśnienie: odpowiedzieć na oryginalne pytanie, zastąpił tna typeof(Animal). Tak więc staje się ulepszona forma Marka t.IsInstanceOfType(x).
ToolmakerSteve

13

GetType()istnieje w każdym typie frameworka, ponieważ jest zdefiniowany w objecttypie podstawowym . Tak więc, niezależnie od samego typu, możesz go użyć do zwrócenia bazowegoType

Więc wszystko, co musisz zrobić, to:

u.GetType() == t

1
Właściwie odpowiedź Erica jest pomocna iw ogóle, ale nie odpowiada faktycznemu pytaniu, jak przeprowadzić test z nieznanym typem w sposób „u is t” opisany w oryginalnym pytaniu, a twoje tak.
Daniel

@Daniel - Niezupełnie. Odpowiedź Dave'a jest poprawna tylko wtedy, gdy chcesz wykluczyć podklasy t. Odpowiedź Erica głównie wyjaśnia, co robić; brakuje tylko wyjaśnienia, gdzie wstawić „t”. Dodam tam komentarz.
ToolmakerSteve

10

Musisz sprawdzić, czy typ Twojej instancji jest równy typowi klasy. Aby uzyskać typ instancji, użyj GetType()metody:

 u.GetType().Equals(t);

lub

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

powinien to zrobić. Oczywiście możesz użyć '==' do porównania, jeśli wolisz.


+1 Ale wolę drugi wybór. u.GetType.Equals(typeof(User));
Omar

Jednym z powodów, dla których jest to mniej bezpieczne niż użycie == - jest to, że jeśli GetType () w jakiś sposób zwróci wartość null - zwróci.
Dave Bish

1
@Fuex, tak mi się wydaje, myślę, że ułatwia to odczytanie kodu, jeśli typeof jest wbudowany, dlatego opublikowałem to w ten sposób, mimo że w przykładzie OP ma już zmienną, tktóra zawiera typ.
Sam Holder

@DaveBish, jeśli GetType zwróci wartość null, martwiłbym się, że wiele rzeczy zacznie rzucać ... ale uwaga, masz oczywiście rację
Sam Holder

@SamHolder Yeah - Jedyna sytuacja jaka by się zdarzyła, byłaby taka, gdyby ktoś przesłonił typ podstawowy i jakoś schrzanił implementację. Na pewno byłoby dziwne.
Dave Bish

4

Aby sprawdzić, czy obiekt jest zgodny ze zmienną danego typu, zamiast pisać

u is t

powinieneś napisać

typeof(t).IsInstanceOfType(u)

1
Jaka jest korzyść z bardziej szczegółowej składni w porównaniu ze składnią „u is t”?
Kyle Humfeld,

@KyleHumfeld Jeśli miałeś Wpisz foo; Obiekt A; nie możesz napisać „A is foo”, ale możesz napisać foo.isInstanceOfType (A)
Timur Nuriyasov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.