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.