Semua benda tumpukan bawaan mewarisi dari Object
; itu masuk akal karena semua objek tumpukan mandiri harus memiliki aspek umum tertentu, seperti cara mengidentifikasi tipenya. Kalau tidak, jika pengumpul sampah memiliki referensi ke objek tumpukan jenis yang tidak diketahui, itu tidak akan memiliki cara untuk mengetahui bit dalam gumpalan memori yang terkait dengan objek yang harus dianggap sebagai referensi ke objek tumpukan lainnya.
Lebih jauh, dalam sistem tipe, akan lebih mudah untuk menggunakan mekanisme yang sama untuk mendefinisikan anggota struktur dan anggota kelas. Perilaku lokasi penyimpanan tipe nilai (variabel, parameter, bidang, slot array, dll.) Sangat berbeda dari lokasi penyimpanan tipe kelas, tetapi perbedaan perilaku tersebut dicapai dalam kompiler kode sumber dan mesin eksekusi (termasuk kompiler JIT) daripada diekspresikan dalam sistem tipe.
Salah satu konsekuensi dari ini adalah bahwa mendefinisikan tipe nilai secara efektif mendefinisikan dua tipe - tipe lokasi penyimpanan dan tipe objek tumpukan. Yang pertama dapat secara implisit dikonversi ke yang terakhir, dan yang terakhir dapat dikonversi ke yang pertama melalui typecast. Kedua jenis konversi ini berfungsi dengan menyalin semua bidang publik dan pribadi dari satu contoh dari jenis yang dipertanyakan. Selain itu, dimungkinkan menggunakan batasan umum untuk memanggil anggota antarmuka pada lokasi penyimpanan tipe nilai secara langsung, tanpa membuat salinannya terlebih dahulu.
Semua ini penting karena referensi ke objek tumpukan tipe nilai berperilaku seperti referensi kelas dan tidak suka tipe nilai. Pertimbangkan, misalnya, kode berikut:
string testEnumerator <T> (T it) di mana T: IEnumerator <string>
{
var it2 = itu;
it.MoveNext ();
it2.MoveNext ();
mengembalikannya. Saat ini;
}
tes public void ()
{
var theList = Daftar baru <string> ();
theList.Add ("Fred");
theList.Add ("George");
theList.Add ("Percy");
theList.Add ("Molly");
theList.Add ("Ron");
var enum1 = theList.GetEnumerator ();
IEnumerator <string> enum2 = enum1;
Debug.Print (testEnumerator (enum1));
Debug.Print (testEnumerator (enum1));
Debug.Print (testEnumerator (enum2));
Debug.Print (testEnumerator (enum2));
}
Jika testEnumerator()
metode ini meneruskan lokasi penyimpanan tipe nilai, it
akan menerima contoh yang bidang publik dan privatnya disalin dari nilai yang diteruskan. Variabel lokal it2
akan menyimpan instance lain yang bidangnya semua disalin it
. Memanggil MoveNext
pada it2
tidak akan mempengaruhi it
.
Jika kode di atas melewati lokasi penyimpanan tipe kelas, maka nilai yang diteruskan it
,, dan it2
, semua akan merujuk ke objek yang sama, dan dengan demikian memanggil MoveNext()
salah satu dari mereka secara efektif akan memanggilnya pada mereka semua.
Perhatikan bahwa casting List<String>.Enumerator
untuk IEnumerator<String>
mengubahnya secara efektif dari tipe nilai ke tipe kelas. Tipe objek heap adalah List<String>.Enumerator
tetapi perilakunya akan sangat berbeda dari tipe nilai dari nama yang sama.
object
dalam kerangka .NET sebagian karena menyediakan beberapa kemampuan dasar di semua objek, sepertiToString()
danGetHashCode()