Ini terlihat aneh terutama untuk pengembang C ++. Di C ++ kami biasa menandai parameter sebagai const
untuk memastikan bahwa statusnya tidak akan diubah dalam metode. Ada juga alasan spesifik C ++ lainnya, seperti passing const ref
untuk melewati ref dan memastikan bahwa status tidak akan berubah. Tapi mengapa kita tidak bisa menandai sebagai parameter metode const di C #?
Mengapa saya tidak dapat mendeklarasikan metode saya seperti berikut?
....
static void TestMethod1(const MyClass val)
{}
....
static void TestMethod2(const int val)
{}
....
c#
language-agnostic
language-design
Penyamaran
sumber
sumber
Jawaban:
Sebagai tambahan dari jawaban bagus lainnya, saya akan menambahkan alasan lain mengapa untuk tidak menempatkan kekonstanan gaya-C ke dalam C #. Kamu berkata:
Jika const benar-benar melakukan itu, itu akan bagus. Const tidak melakukan itu. Const adalah bohong!
Const tidak memberikan jaminan apa pun yang benar-benar dapat saya gunakan. Misalkan Anda memiliki metode yang mengambil benda const. Ada dua penulis kode: orang yang menulis penelepon dan orang yang menulis panggilan . Penulis callee telah membuat metode take a const. Apa yang dapat diasumsikan oleh kedua penulis itu tidak tetap tentang objek?
Tidak ada. Callee bebas untuk membuang const dan memutasi objek, jadi pemanggil tidak memiliki jaminan bahwa memanggil metode yang menggunakan const sebenarnya tidak akan memutasinya. Demikian pula, callee tidak dapat berasumsi bahwa konten objek tidak akan berubah selama tindakan callee; callee bisa memanggil beberapa metode mutasi pada alias non const dari objek const, dan sekarang yang disebut objek const telah berubah .
C-style const tidak memberikan jaminan bahwa objek tidak akan berubah, dan karenanya rusak. Sekarang, C sudah memiliki sistem tipe lemah di mana Anda dapat melakukan interpretasi ulang pemeran ganda menjadi int jika Anda benar-benar menginginkannya, jadi tidak mengherankan bahwa ia memiliki sistem tipe yang lemah sehubungan dengan const juga. Tapi C # dirancang untuk memiliki sistem tipe yang baik , sistem tipe di mana ketika Anda mengatakan "variabel ini berisi string" bahwa variabel sebenarnya berisi referensi ke string (atau null). Kami benar-benar tidak ingin menempatkan pengubah "const" gaya-C ke dalam sistem tipe karena kami tidak ingin sistem tipe menjadi kebohongan . Kami ingin sistem tipe kuat sehingga Anda dapat bernalar dengan benar tentang kode Anda.
Const dalam C adalah pedoman ; itu pada dasarnya berarti "Anda dapat mempercayai saya untuk tidak mencoba mengubah hal ini". Itu seharusnya tidak dalam sistem tipe ; hal-hal dalam sistem tipe haruslah fakta tentang objek yang bisa Anda pertimbangkan, bukan pedoman penggunaannya.
Sekarang, jangan salah paham; hanya karena const di C sangat rusak tidak berarti bahwa seluruh konsep tidak berguna. Yang ingin saya lihat adalah beberapa bentuk anotasi "const" yang benar- benar benar dan berguna di C #, anotasi yang dapat digunakan oleh manusia dan penyusun untuk membantu mereka memahami kode, dan yang dapat digunakan runtime untuk melakukan hal-hal seperti kelumpuhan otomatis dan pengoptimalan lanjutan lainnya.
Misalnya, bayangkan jika Anda bisa "menggambar kotak" di sekitar sebongkah kode dan berkata "Saya jamin kumpulan kode ini tidak melakukan mutasi ke bidang mana pun dari kelas ini" dengan cara yang dapat diperiksa oleh penyusun. Atau gambar kotak yang mengatakan " metode murni ini mengubah keadaan internal objek tetapi tidak dengan cara apa pun yang dapat diamati di luar kotak". Objek seperti itu tidak dapat dengan aman di-multi-threaded secara otomatis tetapi dapat secara otomatis dibuat memo . Ada berbagai macam anotasi menarik yang dapat kami masukkan ke dalam kode yang memungkinkan pengoptimalan yang kaya dan pemahaman yang lebih dalam. Kita bisa melakukan cara yang lebih baik daripada anotasi const gaya-C yang lemah.
Namun, saya tegaskan bahwa ini hanyalah spekulasi . Kami tidak memiliki rencana pasti untuk menempatkan fitur semacam ini ke dalam versi hipotetis C # di masa depan, jika ada, yang belum kami umumkan dengan satu atau lain cara. Ini adalah sesuatu yang saya ingin lihat, dan sesuatu yang mungkin diperlukan oleh penekanan pada komputasi multi-core, tetapi tidak satupun dari ini harus ditafsirkan sebagai prediksi atau jaminan fitur tertentu atau arah masa depan untuk C #.
Sekarang, jika yang Anda inginkan hanyalah anotasi pada variabel lokal yang merupakan parameter yang mengatakan "nilai parameter ini tidak berubah sepanjang metode", maka, tentu, itu akan mudah dilakukan. Kami dapat mendukung lokal "readonly" dan parameter yang akan diinisialisasi satu kali, dan kesalahan waktu kompilasi untuk mengubah metode. Variabel yang dideklarasikan oleh pernyataan "using" sudah seperti itu; kita bisa menambahkan anotasi opsional ke semua lokal dan parameter untuk membuatnya bertindak seperti variabel "menggunakan". Ini tidak pernah menjadi fitur dengan prioritas yang sangat tinggi sehingga tidak pernah diterapkan.
sumber
0xDEADBEEF
. Tetapi keduanya akan menjadi pemrograman yang sangat buruk , dan tertangkap awal dan secara pedih oleh kompiler modern manapun. Di masa mendatang saat menulis jawaban, harap jangan bingung antara apa yang secara teknis mungkin dengan menggunakan pintu belakang bahasa dengan apa yang layak dalam kode dunia nyata yang sebenarnya. Informasi miring seperti ini membingungkan pembaca yang kurang berpengalaman, dan menurunkan kualitas info di SO.Salah satu alasan mengapa tidak ada ketepatan const di C # adalah karena tidak ada di tingkat runtime. Ingatlah bahwa C # 1.0 tidak memiliki fitur apapun kecuali itu adalah bagian dari runtime.
Dan beberapa alasan mengapa CLR tidak memiliki pengertian tentang kebenaran const adalah sebagai contoh:
Kebenaran konstan adalah fitur bahasa yang hanya ada di C ++. Jadi intinya adalah argumen yang sama tentang mengapa CLR tidak memerlukan pengecualian yang dicentang (yang merupakan fitur khusus bahasa Java).
Selain itu, saya rasa Anda tidak dapat memperkenalkan fitur sistem tipe fundamental dalam lingkungan terkelola tanpa merusak kompatibilitas ke belakang. Jadi jangan mengandalkan kebenaran const yang pernah memasuki dunia C #.
sumber
ref
parameter (terutama, dalam kasus metode / properti struct,this
). Jika sebuah metode secara khusus menyatakan bahwa ia tidak akan menulis keref
parameter, maka kompilator harus mengizinkan nilai hanya-baca untuk diteruskan. Sebaliknya, jika suatu metode menyatakan akan menulisthis
, kompilator tidak boleh mengizinkan metode seperti itu dipanggil pada nilai hanya-baca.Saya yakin ada dua alasan mengapa C # tidak benar.
Yang pertama adalah pemahaman . Beberapa programmer C ++ memahami const-correctness. Contoh sederhananya
const int arg
adalah lucu, tetapi saya juga melihatchar * const * const arg
- penunjuk konstan ke petunjuk konstan ke karakter non-konstan. Ketepatan konstan pada pointer ke fungsi adalah tingkat kebingungan yang sama sekali baru.Yang kedua adalah karena argumen kelas adalah referensi yang diteruskan oleh nilai. Ini berarti sudah ada dua tingkat keteguhan yang harus ditangani, tanpa sintaks yang jelas . Titik sandungan serupa adalah koleksi (dan koleksi koleksi, dll).
Const-correctness adalah bagian penting dari sistem tipe C ++. Itu bisa - secara teori - ditambahkan ke C # sebagai sesuatu yang hanya diperiksa pada waktu kompilasi (itu tidak perlu ditambahkan ke CLR, dan tidak akan mempengaruhi BCL kecuali gagasan metode anggota const dimasukkan) .
Namun, saya percaya ini tidak mungkin: alasan kedua (sintaks) akan cukup sulit dipecahkan, yang akan membuat alasan pertama (pemahaman) menjadi lebih dari masalah.
sumber
modopt
danmodreq
pada tingkat metadata untuk menyimpan info tersebut (seperti yang sudah dilakukan C + / CLI - lihatSystem.Runtime.CompilerServices.IsConst
); dan ini bisa juga diperluas ke metode const.const
berarti "konstanta waktu kompilasi" di C #, bukan "hanya-baca tetapi mungkin bisa berubah oleh kode lain" seperti di C ++. Analog kasar dari C ++const
di C # adalahreadonly
, tetapi yang satu itu hanya berlaku untuk bidang. Selain itu, tidak ada gagasan tentang kebenaran konstanta seperti C ++ di C # sama sekali.Alasannya sulit untuk dipastikan, karena ada banyak alasan potensial, tetapi saya kira saya ingin menjaga bahasanya tetap sederhana terlebih dahulu dan terpenting, dan keuntungan yang tidak pasti dari penerapan yang kedua ini.
sumber
Ini dimungkinkan sejak C # 7.2 (Desember 2017 dengan Visual Studio 2017 15.5).
Hanya untuk Struct dan tipe dasar ! , bukan untuk anggota kelas.
Anda harus menggunakan
in
untuk mengirim argumen sebagai masukan dengan referensi. Lihat:Lihat: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier
Sebagai contoh Anda:
sumber