Periksa apakah instance adalah tipe

181

Menggunakan ini untuk memeriksa apakah cmerupakan instance dari TForm.

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

Apakah ada cara yang lebih aman untuk melakukannya selain menggunakan stringsebagai parameter CompareTo()?

Lennie
sumber
20
Saya harap Anda juga tidak melakukannya di Jawa. Java instanceofdan C # isadalah cara yang lebih baik untuk melakukannya.
Powerlord

Jawaban:

410

Perbedaan jawaban di sini memiliki dua arti berbeda.

Jika Anda ingin memeriksa apakah instance adalah tipe yang tepat, maka

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

adalah cara untuk pergi.

Jika Anda ingin tahu apakah cturunan dari TForm atau subkelas maka gunakan is/ as:

if (c is TForm)

atau

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

Sebaiknya jelas dalam benak Anda tentang perilaku mana yang sebenarnya Anda inginkan.

Jon Skeet
sumber
7
Catatan kecil: gunakan "adalah" jika Anda tidak ingin menggunakan hasil pemeran dan gunakan "sebagai" jika Anda mau.
Aviram Fireberger
14
Dengan C # 7 Anda dapat menggabungkan isdan asdengan pencocokan pola:if (x is TForm tf) {…
Richard
39
if(c is TFrom)
{
   // Do Stuff
}

atau jika Anda berencana menggunakan csebagai TForm, gunakan contoh berikut:

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

Contoh kedua hanya perlu memeriksa untuk melihat apakah cbertipe TFormsekali. Dimana jika Anda memeriksa jika melihat apakah cbertipe TFormkemudian melemparkannya, CLR mengalami pemeriksaan tambahan. Ini referensi .

Sunting: Dicuri dari Jon Skeet

Jika Anda ingin memastikan cdari TFormdan bukan kelas mana pun yang mewarisi TForm, maka gunakan

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

Juga, agak dalam nada yang sama

Type.IsAssignableFrom(Type c)

"Benar jika c dan Tipe saat ini mewakili tipe yang sama, atau jika Tipe saat ini ada dalam hierarki warisan c, atau jika Tipe saat ini adalah antarmuka yang mengimplementasikan c, atau jika c adalah parameter tipe generik dan Tipe saat ini merupakan salah satu kendala c. "

Dari sini: http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx

Brad Cunningham
sumber
ini juga favorit pribadi saya. typeof(Class).IsAssignableFrom(object.getType())mirip dengan instanceofoperator Java .
SkidRunner
Apakah itu salah jika mereka tidak berada di cabang yang sama dari hierarki warisan tetapi operator konversi ada?
Paul Stelian
Pertanyaan bagus @PaulStelian. Saya tidak yakin dari atas kepala saya tetapi dugaan saya akan mengembalikan kesalahan dalam situasi itu. Setidaknya itu akan menjadi perilaku saya yang diharapkan. Mungkin jika ada konversi tersirat itu mungkin kembali benar tetapi itu akan aneh.
Brad Cunningham
Adakah yang sudah menginstal Visual Studio untuk mencobanya?
Paul Stelian
1
@ PaulStelian - ini mengembalikan false. Ini dapat dilihat dengan mengikuti tautan dokumen, dan mengamati tidak ada penyebutan konversi. Cara lain untuk memikirkannya adalah T1.IsAssignableFrom(T2)pengembalian truedalam situasi di mana asoperator mengembalikan nilai non-nol, dengan memberikan contoh jenis-jenis tersebut.
ToolmakerSteve
9

Sedikit lebih ringkas daripada jawaban lain jika Anda ingin menggunakan c sebagai TForm:

if(c is TForm form){
    form.DoStuff();
}
Ali Rahman
sumber
3

Coba yang berikut ini

if (c is TForm) { 
 ...
}
JaredPar
sumber
2

Seperti yang telah disebutkan orang lain, kata kunci "adalah". Namun, jika nanti Anda akan melemparkannya ke jenis itu, mis.

TForm t = (TForm)c;

Maka Anda harus menggunakan kata kunci "sebagai".

misalnya TForm t = c as TForm.

Maka Anda dapat memeriksa

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

Jangan gabungkan dengan karena ini adalah pemeriksaan duplikat.

taylonr
sumber
0

Atau

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

atau lebih sederhana

bool isValid = c.GetType() == typeof(TForm);
Gabe
sumber
IMHO: Saya akan menghindari belas kasih langsung (mis. ==). Dalam bahasa berorientasi objek atau mendukung warisan kecuali Anda tahu bahwa Jenis spesifik Anda tidak akan pernah diwarisi dari misalnya sealedKelas. Juga: penggunaan operator ternary yang mengembalikan nilai-nilai boolean (statis / konstan) mengganggu saya, saya tidak akan terlalu terganggu jika itu adalah switchpernyataan.
SkidRunner