Jawaban:
Di .NET sebelum versi 2.0, ""
buat objek sambil string.Empty
buat tidak ada referensi objek , yang membuatnya string.Empty
lebih efisien.
Dalam versi 2.0 dan yang lebih baru. NET, semua kemunculan ""
merujuk ke string literal yang sama, yang artinya ""
setara dengan .Empty
, tetapi masih tidak secepat .Length == 0
.
.Length == 0
adalah pilihan tercepat, tetapi .Empty
menghasilkan kode yang sedikit lebih bersih.
string.IsNullOrEmpty( stringVar )
.
apa perbedaan antara String.Empty dan "", dan apakah keduanya dapat dipertukarkan
string.Empty
adalah bidang baca-saja sedangkan ""
konstanta waktu kompilasi. Tempat-tempat di mana mereka berperilaku berbeda adalah:
Nilai Parameter default dalam C # 4.0 atau lebih tinggi
void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
//... implementation
}
Ekspresi huruf dalam pernyataan sakelar
string str = "";
switch(str)
{
case string.Empty: // Error: A constant value is expected.
break;
case "":
break;
}
Argumen atribut
[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression
// or array creation expression of an attribute parameter type
String.Empty
argumen dalam kebanyakan kasus. Anda benar bahwa semua contoh menunjukkan itu you simply can't put a (run-time) "value" into (compile-time) metadata
dan itulah yang ingin ditunjukkan oleh contoh tersebut.
Jawaban sebelumnya benar untuk .NET 1.1 (lihat tanggal posting yang mereka tautkan: 2003). Pada. NET 2.0 dan yang lebih baru, pada dasarnya tidak ada perbedaan. JIT pada akhirnya akan merujuk objek yang sama pada heap.
Menurut spesifikasi C #, bagian 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
Setiap string literal tidak harus menghasilkan instance string baru. Ketika dua atau lebih liter string yang setara menurut operator kesetaraan string (Bagian 7.9.7) muncul dalam rakitan yang sama, literal string ini merujuk ke instance string yang sama.
Seseorang bahkan menyebutkan ini dalam komentar dari posting Brad Abram
Singkatnya, hasil praktis dari "" vs. String.Empty adalah nol. JIT akan mencari tahu pada akhirnya.
Saya telah menemukan, secara pribadi, bahwa JIT jauh lebih pintar daripada saya dan jadi saya mencoba untuk tidak terlalu pintar dengan optimasi mikro-kompiler seperti itu. JIT akan terbuka untuk () loop, menghapus kode redundan, metode inline, dll lebih baik dan pada waktu yang lebih tepat daripada yang saya atau kompiler C # bisa antisipasi sebelumnya. Biarkan JIT melakukan tugasnya :)
String.Empty
adalah readonly bidang sementara ""
adalah const . Ini berarti Anda tidak dapat menggunakan String.Empty
pernyataan switch karena itu bukan konstanta.
default
kata kunci kita dapat mempromosikan keterbacaan tanpa, mencegah modifikasi yang tidak disengaja, dan memiliki waktu kompilasi yang konstan, meskipun jujur saja, saya masih berpikir String.Empty lebih mudah dibaca daripada default, tetapi lebih lambat untuk mengetik
Perbedaan lainnya adalah bahwa String.Empty menghasilkan kode CIL yang lebih besar. Sementara kode untuk referensi "" dan String.Empty memiliki panjang yang sama, kompiler tidak mengoptimalkan penggabungan string (lihat posting blog Eric Lippert ) untuk argumen String.Empty. Fungsi setara berikut
string foo()
{
return "foo" + "";
}
string bar()
{
return "bar" + string.Empty;
}
buat IL ini
.method private hidebysig instance string foo() cil managed
{
.maxstack 8
L_0000: ldstr "foo"
L_0005: ret
}
.method private hidebysig instance string bar() cil managed
{
.maxstack 8
L_0000: ldstr "bar"
L_0005: ldsfld string [mscorlib]System.String::Empty
L_000a: call string [mscorlib]System.String::Concat(string, string)
L_000f: ret
}
"bar " + (ok ? "" : "error")
Jawaban di atas secara teknis benar, tetapi apa yang mungkin Anda benar-benar ingin gunakan, untuk pembacaan kode terbaik dan peluang pengecualian terkecil adalah String.IsNullOrEmpty (s)
--foo=$BAR
Anda, maka Anda mungkin ingin melihat perbedaan di antara mereka lupa mengatur env var dan mereka tidak melewati flag sama sekali. string.IsNullOrEmpty
sering merupakan bau kode yang Anda belum memvalidasi input Anda dengan benar atau melakukan hal-hal aneh. Anda biasanya tidak boleh menerima string kosong ketika Anda benar-benar bermaksud menggunakan null
, atau sesuatu seperti tipe Maybe / Option.
Saya cenderung menggunakan String.Empty
daripada ""
untuk satu alasan sederhana, namun tidak jelas:
""
dan ""
TIDAK sama, yang pertama sebenarnya memiliki 16 karakter lebar nol di dalamnya. Jelas tidak ada pengembang yang kompeten yang akan menempatkan dan nol karakter lebar ke dalam kode mereka, tetapi jika mereka masuk ke sana, itu bisa menjadi mimpi buruk pemeliharaan.
Catatan:
Saya menggunakan U + FEFF dalam contoh ini.
Tidak yakin apakah SO akan memakan karakter-karakter itu, tetapi cobalah sendiri dengan salah satu dari banyak karakter lebar nol
Saya hanya menemukan ini berkat https://codegolf.stackexchange.com/
Gunakan String.Empty
daripada ""
.
Ini lebih untuk kecepatan daripada penggunaan memori tetapi ini adalah tip yang berguna. Ini
""
adalah literal sehingga akan bertindak sebagai literal: pada penggunaan pertama itu dibuat dan untuk penggunaan berikut referensi dikembalikan. Hanya satu instance dari yang""
akan disimpan dalam memori tidak peduli berapa kali kita menggunakannya! Saya tidak melihat hukuman memori di sini. Masalahnya adalah bahwa setiap kali""
digunakan, loop pembanding dijalankan untuk memeriksa apakah""
sudah ada di kolam intern. Di sisi lain,String.Empty
adalah referensi ke""
tersimpan di zona memori .NET Framework .String.Empty
menunjuk ke alamat memori yang sama untuk aplikasi VB.NET dan C #. Jadi mengapa mencari referensi setiap kali Anda membutuhkannya""
ketika Anda memiliki referensi ituString.Empty
?
Referensi: String.Empty
vs.""
String.Empty tidak membuat objek sedangkan "" melakukannya. Perbedaannya, seperti yang ditunjukkan di sini , adalah sepele.
Semua contoh "" adalah string literal yang diinternir sama (atau seharusnya). Jadi Anda benar-benar tidak akan melemparkan objek baru di heap setiap kali Anda menggunakan "" tetapi hanya membuat referensi ke objek yang sama, diinternir. Karena itu, saya lebih suka string.Empty. Saya pikir itu membuat kode lebih mudah dibaca.
Itu tidak masalah!
Beberapa diskusi terakhir tentang ini:
http://www.codinghorror.com/blog/archives/000185.html
string mystring = "";
ldstr ""
ldstr
mendorong referensi objek baru ke string literal yang disimpan dalam metadata.
string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty
ldsfld
mendorong nilai bidang statis ke tumpukan evaluasi
Saya cenderung menggunakan String.Empty
bukan ""
karena IMHO itu lebih jelas dan kurang VB-ish.
Eric Lippert menulis (17 Juni 2013):
"Algoritma pertama yang pernah saya kerjakan dalam kompiler C # adalah pengoptimal yang menangani penggabungan string. Sayangnya saya tidak berhasil mem-porting optimasi ini ke basis kode Roslyn sebelum saya pergi; semoga seseorang akan dapatkan itu! "
Berikut adalah beberapa hasil Roslyn x64 per Januari 2019. Meskipun pernyataan konsensus dari jawaban lain di halaman ini, tampaknya bagi saya bahwa JIT x64 saat ini memperlakukan semua kasus ini secara identik, ketika semua dikatakan dan dilakukan.
Perhatikan secara khusus, bagaimanapun, bahwa hanya satu dari contoh ini yang benar-benar berakhir dengan panggilan String.Concat
, dan saya menduga itu karena alasan kebenaran yang tidak jelas (sebagai lawan dari pengawasan optimasi). Perbedaan lain tampaknya lebih sulit untuk dijelaskan.
default (String) + {default (String), "", String.Empty}
static String s00() => default(String) + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s01() => default(String) + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s02() => default(String) + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
"" + {default (String), "", String.Empty}
static String s03() => "" + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s04() => "" + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s05() => "" + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
String.Empty + {default (String), "", String.Empty}
static String s06() => String.Empty + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s07() => String.Empty + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s08() => String.Empty + String.Empty;
mov rcx,[String::Empty]
mov rcx,qword ptr [rcx]
mov qword ptr [rsp+20h],rcx
mov rcx,qword ptr [rsp+20h]
mov rdx,qword ptr [rsp+20h]
call F330CF60 ; <-- String.Concat
nop
add rsp,28h
ret
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
AMD64 Release
[MethodImpl(MethodImplOptions.NoInlining)]
'SuppressJitOptimization' = false
Datang dari sudut pandang Entity Framework: EF versi 6.1.3 tampaknya memperlakukan String.Empty dan "" secara berbeda saat memvalidasi.
string.Empty diperlakukan sebagai nilai nol untuk keperluan validasi dan akan melempar kesalahan validasi jika digunakan pada bidang Diperlukan (dikaitkan); dimana "" akan melewati validasi dan tidak membuang kesalahan.
Masalah ini dapat diatasi dalam EF 7+. Referensi: - https://github.com/aspnet/EntityFramework/issues/2610 ).
Sunting: [Diperlukan (AllowEmptyStrings = true)] akan menyelesaikan masalah ini, memungkinkan string.Empty untuk memvalidasi.
Karena String.Empty bukan konstanta waktu kompilasi, Anda tidak dapat menggunakannya sebagai nilai default dalam definisi fungsi.
public void test(int i=0,string s="")
{
// Function Body
}
public void test(int i=0, string s=string.Empty) {}
tidak akan mengkompilasi dan mengatakan "Nilai parameter default untuk 's' harus berupa konstanta waktu kompilasi. Jawaban OP berfungsi.
Saat Anda memindai kode secara visual, "" tampak berwarna seperti string yang diwarnai. string.Empty tampak seperti akses anggota kelas biasa. Selama tampilan cepat, lebih mudah menemukan "" atau intuisi maknanya.
Temukan string (stack overflow colorization tidak membantu, tetapi dalam VS ini lebih jelas):
var i = 30;
var f = Math.Pi;
var s = "";
var d = 22.2m;
var t = "I am some text";
var e = string.Empty;
\u00ad
.
Semua orang di sini memberikan klarifikasi teoretis yang baik. Saya memiliki keraguan yang sama. Jadi saya mencoba coding dasar di atasnya. Dan saya menemukan perbedaan. Inilah bedanya.
string str=null;
Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference.
string str = string.Empty;
Console.WriteLine(str.Length); // 0
Jadi sepertinya "Null" berarti benar-benar batal & "String.Empty" berarti Ini berisi semacam nilai, tetapi itu kosong.
""
versus string.Empty
. Hanya ketika mencoba untuk mengetahui apakah string kosong, null
telah disebutkan.
string.Empty
dan apa alasan di balik menyatakannya sebagaireadonly
ganticonst
.