Sprawdź, czy instancja jest typu


181

Używanie tego do sprawdzenia, czy cjest to instancja TForm.

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

Czy istnieje bardziej bezpieczny sposób na zrobienie tego niż użycie stringparametru jako parametru CompareTo()?


20
Mam nadzieję, że nie zrobisz tego również w Javie. Java instanceofi C # isto znacznie lepsze sposoby na zrobienie tego.
— Władca

Odpowiedzi:


410

Różne odpowiedzi tutaj mają dwa różne znaczenia.

Jeśli chcesz sprawdzić, czy instancja jest tego samego typu, to

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

jest droga.

Jeśli chcesz wiedzieć, czy cjest instancją TForm czy podklasą, użyj is/ as:

if (c is TForm)

lub

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

Warto jasno powiedzieć, które z tych zachowań naprawdę chcesz.


7
Mała uwaga: użyj „jest”, jeśli nie chcesz użyć wyniku rzutowania, i użyj „jak”, jeśli to zrobisz.
— Aviram Fireberger,

14
Z C # 7 możesz łączyć isi asdopasowywać wzory:if (x is TForm tf) {…
— Richard

39
if(c is TFrom)
{
   // Do Stuff
}

lub jeśli planujesz używać cjako a TForm, skorzystaj z następującego przykładu:

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

Drugi przykład wymaga tylko sprawdzenia, czy cjest typu TFormjeden raz. Gdzie, jeśli sprawdzisz, czy cjest typu, TForma następnie rzucisz go, CLR przechodzi dodatkową kontrolę. Oto odniesienie .

Edycja: Skradziony od Jona Skeeta

Jeśli chcesz się upewnić, cma TFormi nie każda klasa dziedziczy TForm, a następnie użyć

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


10

Również nieco w tym samym stylu

Type.IsAssignableFrom(Type c)

„Prawda, jeśli c i bieżący typ reprezentują ten sam typ, lub jeśli bieżący typ znajduje się w hierarchii dziedziczenia c, lub jeśli bieżący typ jest interfejsem implementowanym przez c lub jeśli c jest parametrem typu ogólnego i bieżącym typem reprezentuje jedno z ograniczeń c. ”

Stąd: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx


to także mój osobisty faworyt. typeof(Class).IsAssignableFrom(object.getType())podobny do instanceofoperatora Java .
— SkidRunner,

Czy daje wartość fałsz, jeśli nie znajdują się w tej samej gałęzi hierarchii dziedziczenia, ale istnieje operator konwersji?
— Paul Stelian,

Dobre pytanie @PaulStelian. Nie jestem pewien, czy z góry mam głowę, ale domyślam się, że w tej sytuacji zwróciłby fałsz. Takie byłoby przynajmniej moje oczekiwane zachowanie. Możliwe, że jeśli istnieje domniemana konwersja, może zwrócić wartość true, ale byłoby to dziwne.
— Brad Cunningham

Ktoś, kto ma zainstalowany program Visual Studio, aby go wypróbować?
— Paul Stelian

1
@PaulStelian - zwraca false. Można to zobaczyć, klikając link do dokumentu i zauważając, że nie ma wzmianki o konwersjach. Innym sposobem myślenia o tym jest T1.IsAssignableFrom(T2)zwracanie truew sytuacjach, w których asoperator zwraca wartość inną niż null, biorąc pod uwagę instancje tego typu.
— ToolmakerSteve

9

Trochę bardziej kompaktowy niż inne odpowiedzi, jeśli chcesz użyć c jako TForm:

if(c is TForm form){
    form.DoStuff();
}


2

Jak wspomnieli inni, słowo kluczowe „jest”. Jeśli jednak zamierzasz później rzucić go na ten typ, np.

TForm t = (TForm)c;

Następnie powinieneś użyć słowa kluczowego „as”.

na przykład TForm t = c as TForm.

Następnie możesz sprawdzić

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

Nie łącz tak jak z, ponieważ jest to duplikat czeku.



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

lub prościej

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

IMHO: Unikałbym bezpośredniego współczucia (tj. ==). W językach obiektowych lub zorientowanych obsługujących dziedziczenie, chyba że wiesz, że określony typ nigdy nie zostanie odziedziczony na przykład z sealedklasy. Także: korzystanie z trójskładnikowego operatora zwracającego (statyczne / stałe) wartości logiczne przeszkadza mi, mniej bym się martwił, gdyby to była switchinstrukcja.
— SkidRunner,
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.