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()?


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.


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
}


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


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();
}


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.



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

atau lebih sederhana

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.