Berdebat ramah dengan rekan kerja tentang hal ini. Kami memiliki beberapa pemikiran tentang ini, tetapi bertanya-tanya apa pendapat orang-orang SO tentang ini?
Berdebat ramah dengan rekan kerja tentang hal ini. Kami memiliki beberapa pemikiran tentang ini, tetapi bertanya-tanya apa pendapat orang-orang SO tentang ini?
Jawaban:
Salah satu alasannya adalah tidak ada dukungan CLR untuk bahasa lokal yang hanya bisa dibaca. Hanya baca diterjemahkan ke dalam opcode awal CLR / CLI. Bendera ini hanya dapat diterapkan ke bidang dan tidak memiliki arti untuk lokal. Faktanya, menerapkannya ke lokal kemungkinan akan menghasilkan kode yang tidak dapat diverifikasi.
Ini tidak berarti bahwa C # tidak bisa melakukan ini. Tetapi itu akan memberikan dua arti yang berbeda pada konstruksi bahasa yang sama. Versi untuk penduduk lokal tidak akan memiliki pemetaan yang setara dengan CLR.
readonly
kata kunci untuk bidang perlu didukung oleh CLI karena efeknya adalah terlihat majelis lainnya. Artinya adalah variabel hanya memiliki satu tugas dalam metode pada waktu kompilasi.
const
(yang di C ++ lebih seperti C # readonly
daripada C # const
, meskipun dapat memainkan kedua peran tersebut). Namun C ++ mendukung const
variabel otomatis lokal. Oleh karena itu, kurangnya dukungan CLR untuk C # readonly
untuk variabel lokal, tidak relevan.
using
dan out
melakukan hal itu dan dunia tidak runtuh.
Saya pikir itu adalah penilaian yang buruk dari arsitek C #. modifier readonly pada variabel lokal membantu menjaga ketepatan program (seperti asserts) dan berpotensi membantu compiler mengoptimalkan kode (setidaknya dalam kasus bahasa lain). Fakta bahwa itu tidak diizinkan di C # sekarang, adalah argumen lain bahwa beberapa "fitur" C # hanyalah penegakan gaya pengkodean pribadi penciptanya.
Mengatasi jawaban Jared, itu mungkin hanya akan menjadi fitur waktu kompilasi - kompilator akan melarang Anda menulis ke variabel setelah deklarasi awal (yang harus menyertakan tugas).
Dapatkah saya melihat nilai ini? Secara potensial - tapi tidak banyak, jujur saja. Jika Anda tidak dapat dengan mudah mengetahui apakah suatu variabel akan ditempatkan di tempat lain dalam metode, maka metode Anda terlalu panjang.
Untuk apa layak ini, Java memiliki fitur ini (menggunakan final
modifier) dan saya sudah sangat jarang melihatnya digunakan selain dalam kasus-kasus di mana ia memiliki untuk digunakan untuk memungkinkan variabel yang akan diambil oleh kelas dalam anonim - dan di mana itu adalah digunakan, ini memberi saya kesan berantakan daripada informasi yang berguna.
readonly
/ final
nilai dari variabel dengan nya val
dan var
kata kunci. Dalam kode Scala, lokal sangat sering val
digunakan (dan, pada kenyataannya, lebih disukai daripada lokal ). Saya menduga bahwa alasan utama pengubah tidak digunakan lebih sering di Java adalah a) kekacauan dan b) kemalasan. var
final
readonly
tidak akan terlalu penting. Di sisi lain, untuk variabel lokal yang digunakan dalam closure, readonly
dalam banyak kasus akan membiarkan kompilator menghasilkan kode yang lebih efisien. Saat ini, saat eksekusi memasuki blok yang berisi closure, compiler harus membuat objek heap baru untuk variabel closed-over, bahkan jika tidak ada kode yang akan menggunakan closure yang dieksekusi . Jika sebuah variabel hanya-baca, kode di luar closure dapat menggunakan variabel normal; hanya ketika sebuah delegasi dibuat untuk penutupan ...
Proposal yang hanya dibaca penduduk setempat dan parameternya dibahas secara singkat oleh tim desain C # 7. Dari Catatan Rapat Desain C # untuk 21 Jan 2015 :
Parameter dan penduduk lokal dapat ditangkap oleh lambda dan dengan demikian diakses secara bersamaan, tetapi tidak ada cara untuk melindunginya dari masalah negara bersama: keduanya tidak dapat hanya dibaca.
Secara umum, sebagian besar parameter dan banyak lokal tidak pernah dimaksudkan untuk ditetapkan setelah mereka mendapatkan nilai awalnya. Membiarkan hanya membaca pada mereka akan mengungkapkan maksud itu dengan jelas.
Satu masalah adalah bahwa fitur ini mungkin merupakan "gangguan yang menarik". Meskipun "hal yang benar" untuk dilakukan hampir selalu membuat parameter dan penduduk setempat hanya dapat dibaca, itu akan mengacaukan kode secara signifikan untuk melakukannya.
Ide untuk mengurangi sebagian hal ini adalah dengan mengizinkan kombinasi readonly var pada variabel lokal untuk dikontrakkan ke val atau sesuatu yang singkat seperti itu. Secara lebih umum, kami dapat mencoba untuk hanya memikirkan kata kunci yang lebih pendek daripada kata kunci yang sudah ada untuk mengekspresikan hanya-baca.
Diskusi berlanjut di repo Desain Bahasa C #. Pilih untuk menunjukkan dukungan Anda. https://github.com/dotnet/csharplang/issues/188
Ini adalah pengawasan bagi desainer bahasa c #. F # memiliki kata kunci val dan didasarkan pada CLR. Tidak ada alasan C # tidak dapat memiliki fitur bahasa yang sama.
Saya adalah rekan kerja itu dan itu tidak ramah! (hanya bercanda)
Saya tidak akan menghilangkan fitur tersebut karena lebih baik menulis metode singkat. Ini seperti mengatakan Anda tidak boleh menggunakan utas karena sulit. Beri aku pisau dan biarkan aku bertanggung jawab untuk tidak memotong diriku sendiri.
Secara pribadi, saya ingin kata kunci jenis "var" lain seperti "inv" (invarient) atau "rvar" untuk menghindari kekacauan. Saya telah mempelajari F # akhir-akhir ini dan menemukan hal yang kekal itu menarik.
Tidak pernah tahu Jawa punya ini.
Saya ingin variabel readonly lokal dengan cara yang sama seperti yang saya suka variabel const lokal . Tetapi memiliki prioritas yang kurang dari topik lainnya.
Mungkin prioritasnya adalah alasan yang sama bagi desainer C # untuk tidak (belum!) Mengimplementasikan fitur ini. Tapi itu harus mudah (dan kompatibel ke belakang) untuk mendukung variabel hanya baca lokal di versi mendatang.
Hanya baca berarti satu-satunya tempat variabel instance dapat disetel adalah di konstruktor. Saat mendeklarasikan variabel secara lokal, ia tidak memiliki instance (hanya dalam cakupan), dan tidak dapat disentuh oleh konstruktor.
Saya tahu, ini tidak menjawab mengapa pertanyaan Anda. Bagaimanapun, mereka yang membaca pertanyaan ini mungkin menghargai kode di bawah ini.
Jika Anda benar-benar khawatir dengan masalah saat menimpa variabel lokal yang seharusnya hanya disetel sekali, dan Anda tidak ingin menjadikannya variabel yang lebih dapat diakses secara global, Anda dapat melakukan sesuatu seperti ini.
public class ReadOnly<T>
{
public T Value { get; private set; }
public ReadOnly(T pValue)
{
Value = pValue;
}
public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
{
if (object.ReferenceEquals(pReadOnlyT, null))
{
return object.ReferenceEquals(pT, null);
}
return (pReadOnlyT.Value.Equals(pT));
}
public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
{
return !(pReadOnlyT == pT);
}
}
Contoh penggunaan:
var rInt = new ReadOnly<int>(5);
if (rInt == 5)
{
//Int is 5 indeed
}
var copyValueOfInt = rInt.Value;
//rInt.Value = 6; //Doesn't compile, setter is private
Mungkin tidak sesedikit kode rvar rInt = 5
tetapi berhasil.
Anda dapat mendeklarasikan variabel lokal readonly di C #, jika Anda menggunakan compiler interaktif C # csi
:
>"C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
Anda juga dapat mendeklarasikan variabel lokal hanya baca dalam .csx
format skrip.
message
bukan variabel di sini, ini dikompilasi ke bidang. Ini bukan nitpicking karena perbedaannya jelas ada dalam C # interaktif juga: int x; Console.WriteLine(x)
adalah interaktif hukum C # (karena x
merupakan bidang dan diinisialisasi secara implisit) tetapi void foo() { int x; Console.WriteLine(x); }
tidak (karena x
merupakan variabel dan digunakan sebelum ditetapkan). Juga, Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
akan mengungkapkan bahwa x
itu benar-benar bidang dan bukan variabel lokal.
c # sudah memiliki var hanya-baca, meskipun dalam sintaks yang agak berbeda:
Pertimbangkan baris berikut:
var mutable = myImmutableCalculationMethod();
readonly var immutable = mutable; // not allowed in C# 8 and prior versions
return immutable;
Dibandingkan dengan:
var mutable = myImmutableCalculationMethod();
string immutable() => mutable; // allowed in C# 7
return immutable();
Memang, solusi pertama mungkin lebih sedikit kode untuk ditulis. Tapi potongan kedua akan membuat eksplisit baca, saat mereferensikan variabel.
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.
menggunakan const
kata kunci untuk membuat variabel hanya baca.
referensi: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
public class SealedTest
{
static void Main()
{
const int c = 707;
Console.WriteLine("My local constant = {0}", c);
}
}
const
mana variabel hanya dapat ditetapkan selama inisialisasi — bukan gaya csharp di const
mana hanya ekspresi waktu kompilasi yang dapat digunakan. Misalnya, Anda tidak dapat melakukannya const object c = new object();
tetapi orang readonly
lokal akan mengizinkan Anda melakukan ini.