Di banyak daftar MSIL, saya telah mengamati hal-hal berikut:
System.Nullable`1<!0> etc ...
atau
class !0 etc ...
Apa artinya !0
dalam keadaan seperti ini?
Ini adalah kekhasan dari decompiler yang Anda gunakan untuk melihat rakitan .NET. Ini adalah perilaku ildasm.exe, yang lain seperti Reflector atau ILSpy mendapatkan hak ini. Pemrogram Microsoft yang menulisnya mengambil jalan pintas, dia menghasilkan string dari IL yang hanya menampilkan argumen tipe seperti yang dikodekan, tanpa menulis kode tambahan untuk mencari nama argumen tipe dalam metadata.
Anda perlu membaca !n
sebagai argumen tipe ke-n dari tipe generik. Dimana! 0 berarti "argumen tipe pertama",! 1 berarti "argumen tipe kedua", dan sebagainya. Untuk Nullable <>, Anda tahu bahwa '! 0` berarti' T 'dari artikel MSDN.
Anda mungkin juga menemukan sesuatu seperti !!T
. Dua tanda seru menunjukkan argumen tipe untuk metode generik . Kali ini, ildasm.exe tidak mencari jenis nama argumen daripada menggunakan !!0
. Mengapa programmer mengambil jalan pintas pada tipe generik tetapi tidak pada metode generik sulit untuk merekayasa balik. Ildasm adalah program yang cukup unik dan ditulis dalam gaya pengkodean C ++ yang sangat berbeda dari kode C ++ lainnya di .NET. Tidak disiplin, kemungkinan tidak nol bahwa ini adalah tugas magang :)
Sufiks `1 pada" Nullable "adalah pengkodean normal untuk nama tipe generik, ini menunjukkan tipe generik memiliki satu argumen tipe. Dengan kata lain, untuk Nullable <> Anda tidak akan pernah melihat! 1 digunakan.
Jadi cukup dibaca !0
sebagai "T". Atau gunakan decompiler yang lebih baik.
Itu adalah parameter tipe generik.
Mereka posisional.
Dekompilasi beberapa kode umum untuk melihat bagaimana mereka digunakan (bandingkan IL vs C #).
!T
dan!!T
, tergantung apakah parameter generik dari kelas yang memuat atau metode ... Sama jika saya menggunakan ildasmldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionary
ataucall instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool)
. IL mentah hanya menggunakan argumen posisi, meskipun -!TKey
ini sudah merupakan upaya untuk membuat IL lebih mudah dibaca. Mungkin tidak selalu berhasil dengan baik? Spesifikasi ECMA selalu menggunakan posisi!0
/!00
juga.