Di. Net mengapa String.Empty hanya membaca bukan konstanta? Saya hanya ingin tahu apakah ada yang tahu alasan di balik keputusan itu.
Di. Net mengapa String.Empty hanya membaca bukan konstanta? Saya hanya ingin tahu apakah ada yang tahu alasan di balik keputusan itu.
Jawaban:
Alasan yang static readonly
digunakan alih-alih const
adalah karena digunakan dengan kode yang tidak dikelola, seperti yang ditunjukkan oleh Microsoft di sini dalam Siaran Bersama Common Language Infrastructure 2.0 Release . File yang akan dilihat adalah sscli20\clr\src\bcl\system\string.cs
.
Konstanta kosong memegang nilai string kosong. Kita perlu memanggil konstruktor String agar kompiler tidak menandainya sebagai literal.
Menandai ini sebagai literal berarti itu tidak muncul sebagai bidang yang bisa kita akses dari asli.
Saya menemukan informasi ini dari artikel praktis ini di CodeProject .
String.Empty
lagi karena alasan itu saja.
Saya pikir ada banyak kebingungan dan tanggapan buruk di sini.
Pertama-tama, const
bidang adalah static
anggota ( bukan anggota contoh ).
Periksa bagian 10.4 Konstanta dari spesifikasi bahasa C #.
Meskipun konstanta dianggap sebagai anggota statis, deklarasi konstan tidak memerlukan atau mengizinkan pengubah statis.
Jika public const
anggota statis, orang tidak dapat mempertimbangkan bahwa konstanta akan membuat Obyek baru.
Dengan ini, baris kode berikut melakukan hal yang persis sama sehubungan dengan pembuatan Objek baru.
public static readonly string Empty = "";
public const string Empty = "";
Berikut adalah catatan dari Microsoft yang menjelaskan perbedaan antara 2:
Kata kunci readonly berbeda dari kata kunci const. Bidang const hanya dapat diinisialisasi pada deklarasi bidang. Bidang baca-saja dapat diinisialisasi baik di deklarasi atau di konstruktor. Oleh karena itu, bidang hanya baca dapat memiliki nilai yang berbeda tergantung pada konstruktor yang digunakan. Juga, sementara bidang const adalah konstanta waktu kompilasi, bidang readonly dapat digunakan untuk konstanta runtime, ...
Jadi saya menemukan bahwa satu-satunya jawaban yang masuk akal di sini adalah jawaban Jeff Yates.
const string
dan static readonly string
melakukan hal yang sama. Nilai-nilai konstanta digantikan dalam kode tertaut sedangkan nilai-nilai statis baca dirujuk. Jika Anda memiliki const
di perpustakaan A yang digunakan oleh perpustakaan B, perpustakaan B akan mengganti semua referensi ke const
variabel itu dengan nilai literalnya; jika variabel itu static readonly
sebaliknya, itu akan dirujuk dan nilainya ditentukan saat runtime.
String.Empty read only instead of a constant?
Jika Anda membuat string konstan , maka kompiler diganti dengan string sebenarnya di mana pun Anda menyebutnya dan Anda mengisi kode Anda dengan string yang sama di seluruh dan ketika kode berjalan juga perlu membaca lagi dan lagi bahwa string dari memori yang berbeda data.
Jika Anda membiarkan string hanya dibaca di satu tempat saja String.Empty
, program menyimpan string yang sama hanya di satu tempat dan membacanya, atau merujuknya - menjaga data dalam memori minimum.
Juga jika Anda mengkompilasi dll menggunakan String.Empty sebagai const, dan untuk alasan apa pun String.Empty berubah, maka dll yang dikompilasi tidak akan berfungsi lagi sama, karena cost
membuat kode di dalam untuk benar-benar menyimpan salinan string. pada setiap panggilan.
Lihat kode ini misalnya:
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
akan datang oleh kompiler sebagai:
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
dan panggilan perakitan
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
Sunting: Kesalahan ketik yang diperbaiki
Jawaban ini ada untuk tujuan historis.
Semula:
Karena String
adalah kelas dan karenanya tidak dapat menjadi konstanta.
Diskusi Lanjutan:
Banyak dialog bermanfaat yang dibuat dalam memeriksa jawaban ini, dan bukannya menghapusnya, konten ini direproduksi secara langsung:
Dalam .NET, (tidak seperti dalam Java) string dan String persis sama. Dan ya, Anda dapat memiliki string konstanta literal dalam. NET - DrJokepu 3 Februari 2009 di 16:57
Apakah Anda mengatakan bahwa Kelas tidak dapat memiliki konstanta? - StingyJack 3 Feb 09 di 16:58
Ya, objek harus digunakan hanya baca. Hanya struct yang dapat melakukan konstanta. Saya pikir ketika Anda menggunakan
string
bukannyaString
kompiler mengubah const menjadi hanya untuk Anda. Semua itu berkaitan dengan menjaga programmer C senang. - Garry Shutler 3 Feb 09 di 16:59tvanfosson hanya menjelaskannya sedikit lebih verbose. "X tidak boleh berupa konstanta, karena yang mengandung Y adalah sebuah kelas" hanya sedikit terlalu bebas konteks;) - Leonidas 3 Februari 2009 di 17:01
string.Empty adalah properti statis yang mengembalikan instance dari kelas String, yaitu string kosong, bukan kelas string itu sendiri. - tvanfosson 3 Feb 09 di 17:01
Empty adalah instance readonly (bukan properti) dari kelas String. - senfo 3 Februari 2009 pada 17:02
Kepala sakit. Saya masih berpikir saya benar, tetapi sekarang saya kurang yakin. Diperlukan penelitian malam ini! - Garry Shutler 3 Februari 2009 pada 17:07
String kosong adalah turunan dari kelas string. Kosong adalah bidang statis (bukan properti, saya berdiri dikoreksi) pada kelas String. Pada dasarnya perbedaan antara pointer dan hal itu menunjuk. Jika tidak dibaca hanya kita bisa mengubah contoh yang bidang isian merujuk. - tvanfosson 3 Februari 2009 pada 17:07
Garry, Anda tidak perlu melakukan riset apa pun. Pikirkan tentang itu. String adalah kelas. Kosong adalah turunan dari String. - senfo 3 Februari 2009 pada 17:12
Ada sesuatu yang saya tidak mengerti: bagaimana mungkin konstruktor statis dari kelas String membuat turunan dari kelas String? Bukankah itu semacam skenario "ayam atau telur"? - DrJokepu 3 Feb 09 pada 17:12 5
Jawaban ini akan benar untuk hampir semua kelas lain selain System.String. .NET melakukan banyak kinerja casing khusus untuk string, dan salah satunya adalah bahwa Anda BISA memiliki konstanta string, coba saja. Dalam hal ini, Jeff Yates memiliki jawaban yang benar. - Joel Mueller 3 Februari 2009 pada 19:25
Seperti dijelaskan dalam §7.18, ekspresi-konstan adalah ekspresi yang dapat sepenuhnya dievaluasi pada waktu kompilasi. Karena satu-satunya cara untuk membuat nilai non-null dari tipe referensi selain string adalah dengan menerapkan operator baru, dan karena operator baru tidak diizinkan dalam ekspresi konstan, satu-satunya nilai yang mungkin untuk konstanta tipe referensi selain string adalah nol. Dua komentar sebelumnya diambil langsung dari spesifikasi bahasa C # dan menegaskan kembali apa yang disebutkan Joel Mueller. - senfo 4 Februari 2009 pada 15:05 5