Perbedaan antara tipe referensi dan tipe nilai pada dasarnya adalah tradeoff kinerja dalam desain bahasa. Jenis referensi memiliki beberapa overhead pada konstruksi dan penghancuran dan pengumpulan sampah, karena mereka dibuat di heap. Tipe nilai di sisi lain memiliki overhead pada pemanggilan metode (jika ukuran data lebih besar dari pointer), karena seluruh objek disalin daripada hanya pointer. Karena string dapat (dan biasanya) jauh lebih besar dari ukuran pointer, mereka dirancang sebagai tipe referensi. Juga, seperti yang ditunjukkan Servy, ukuran tipe nilai harus diketahui pada waktu kompilasi, yang tidak selalu berlaku untuk string.
Pertanyaan tentang mutabilitas adalah masalah yang terpisah. Baik tipe referensi dan tipe nilai bisa berubah-ubah atau tidak berubah. Jenis nilai biasanya tidak berubah, karena semantik untuk jenis nilai yang dapat berubah dapat membingungkan.
Jenis referensi umumnya bisa berubah, tetapi dapat dirancang sebagai tidak berubah jika masuk akal. String didefinisikan sebagai tidak dapat diubah karena memungkinkan pengoptimalan tertentu. Misalnya, jika string literal yang sama muncul beberapa kali dalam program yang sama (yang cukup umum), kompiler dapat menggunakan kembali objek yang sama.
Jadi mengapa "==" kelebihan beban untuk membandingkan string dengan teks? Karena itu adalah semantik yang paling berguna. Jika dua string sama dengan teks, mereka mungkin atau mungkin tidak menjadi referensi objek yang sama karena optimasi. Jadi membandingkan referensi sama sekali tidak berguna, sementara membandingkan teks hampir selalu seperti yang Anda inginkan.
Berbicara lebih umum, Strings memiliki apa yang disebut semantik nilai . Ini adalah konsep yang lebih umum daripada tipe nilai, yang merupakan detail implementasi spesifik C #. Tipe nilai memiliki semantik nilai, tetapi tipe referensi juga memiliki semantik nilai. Ketika suatu tipe memiliki semantik nilai, Anda tidak dapat benar-benar mengetahui apakah implementasi yang mendasarinya adalah tipe referensi atau tipe nilai, sehingga Anda dapat mempertimbangkannya sebagai detail implementasi.
is
mengesampingkan tes), jawabannya mungkin "karena alasan historis". Kinerja penyalinan tidak dapat menjadi alasan karena tidak perlu menyalin objek yang tidak dapat diubah secara fisik. Sekarang tidak mungkin untuk mengubah tanpa melanggar kode yang benar-benar menggunakanis
cek (atau kendala serupa).