Apa perbedaan antara System.Type dan System.RuntimeType di C #?

90

Saya mencoba melakukan beberapa tes konvensi hari ini, dan mendapatkan semua tipe dalam sebuah majelis (dengan menelepon Assembly.GetTypes()), ketika saya menemukan sesuatu:

System.RuntimeType:[First.Namespace.FirstClass]

Setiap kali saya mencoba membandingkan tipe itu dengan typeof(FirstClass), mereka tidak sama. Jadi, ketika saya mencoba menemukan semua tipe yang mengandung FirstClasssebagai parameter umum, saya tidak menemukan satupun.

Apa perbedaan antara System.RuntimeTypedan System.Type?

Apakah ada cara untuk menyelesaikan masalah saya?

Edgar Gonzalez
sumber
6
Dapatkah Anda memberikan program kecil yang menunjukkan masalah yang Anda alami?
Eric Lippert
Tadinya saya mau, tapi sudah mendapat jawabannya: P
Edgar Gonzalez

Jawaban:

109

System.RuntimeTypeadalah kelas beton yang diturunkan dari kelas dasar abstrak System.Type. Karena System.RuntimeTypetidak bersifat publik, Anda biasanya akan menemukan contohnya sebagai System.Type.

Kebingungan bisa muncul ketika Anda mencoba untuk mendapatkan tipe sebuah objek dan secara keliru memanggil GetType()objek lain yang mewakili tipe objek pertama, daripada hanya menggunakan objek itu secara langsung. Kemudian Type.ToString()akan kembali "System.RuntimeType"ketika objek yang dipanggil mewakili Tipe:

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

Misalnya, dalam posting blog ini seseorang mencoba mendapatkan jenis kolom dalam database, melakukan sesuatu seperti ini:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Karena val sudah menjadi objek Tipe, val.GetType () akan mengembalikan objek Tipe lain yang mewakili tipe System.RuntimeTimekarena ini adalah tipe konkret yang digunakan untuk merepresentasikan objek tipe asli. Posting blog kemudian menunjukkan beberapa tipu daya refleksi yang tidak perlu, untuk mendapatkan jenis objek tipe asli, padahal yang dibutuhkan hanyalah:

Type type = reader.GetFieldType(index) as Type;

Jadi jika Typeobjek Anda melaporkan bahwa itu mewakili a System.RuntimeType, pastikan Anda tidak secara tidak sengaja memanggil GetType()tipe yang sudah Anda dapatkan.

Ergwun
sumber
Cuplikan kode pertama hanya memeriksa apakah objeknya adalah turunan — itu akan Typemengembalikan nilai true meskipun Anda lulus typeof(int). Potongan kode kedua tidak berfungsi untuk membandingkan typeof(string).GetType()dan typeof(Type).
Mark Cidade
Inilah yang saya cari! Saya menemukan postingan Thomas Danecker tetapi tidak dari Doogal Bell
Edgar Gonzalez
1
@Tokopedia Terlihat bagus, terima kasih. Memiliki jawaban tetap agar lebih bermanfaat, semoga menghilangkan kebingungan yang saya tunjukkan dengan mengutip posting blog itu.
Ergwun
@ Edgar Gonzalez: Entri blog yang saya rujuk sebenarnya agak menyesatkan. Silakan lihat jawaban saya yang diperbarui untuk info yang lebih baik.
Ergwun
4

Dari jawaban untuk Perbedaan antara System.Type dan System.RuntimeType oleh Thomas Danecker :

System.Type adalah kelas dasar abstrak. CLR memiliki implementasi konkretnya di tipe internal System.RuntimeType. Karena typeof (string) ini. GetType () mengembalikan RuntimeType tetapi typeof (Type) mengembalikan Type normal. Menggunakan metode .Equals sebenarnya adalah sebuah object.ReferenceEquals yang mengembalikan nilai false. Untuk mendapatkan hasil yang diharapkan, Anda dapat menggunakan type.IsInstanceOfType (elemen). Ini juga akan mengembalikan nilai true jika elemen berjenis turunan. Jika Anda ingin memeriksa jenis yang tepat, nilai kembalian false dari metode Anda adalah hasil yang diinginkan. Anda juga dapat menggunakan checkType (arrayType, Type.GetType ("System.RuntimeType")) untuk memeriksa RuntimeType.

John Saunders
sumber
1
"sebenarnya adalah" - Bisakah kita mendapatkan koreksi tata bahasa. Ini seperti inti dari semuanya dan tidak masuk akal.
N73k
2

Secara singkat...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

Cara saya sekarang memikirkannya adalah bahwa System.Typetipe dasar untuk tipe yang mewakili hasil permintaan tipe objek saat runtime, yaitu System.RuntimeType. Jadi, ketika Anda meminta tipe objek, seperti "".GetType(),, instance yang System.Typedikembalikan adalah turunannya System.RuntimeType,. Sebenarnya, orang harus berharap bahwa typeof(System.Type).GetType()seharusnya System.RuntimeTypejuga, tetapi saya pikir kerangka kerjanya secara khusus mencegah ... simetri ini.

George
sumber