Apa gunanya properti string.Empty


35

Mengapa properti itu string foo = string.Emptytermasuk dalam BCL? Tampaknya lebih verbose dan tidak lebih jelas daripada hanya menggunakan string kosong ( string foo = "")


6
Nitpick: Ini bukan bagian dari bahasa. Itu adalah bagian dari BCL. VB.NET dan F # dapat menggunakannya, serta setiap bahasa .NET lainnya.
Oded

19
Karena jika tidak, Anda tidak dapat melakukan hal-hal jahat seperti typeof(string).GetField("Empty").SetValue(null, " ");;)
Mason Wheeler

1
@MasonWheeler - Kegembiraan refleksi. Untuk kejahatan nyata, Anda perlu introspeksi, eh?
Oded

1
@MasonWheeler, +1. Ya Tuhan, kacamata, mereka tidak melakukan apa pun!]
Machado

1
@MasonWheeler Itu murni, kejahatan suling. Aku suka ini. Pertanyaan jika Anda tertarik: bukankah lebih aman (dan benar-benar performan) untuk menuliskannya public static string Empty { get { return string.Intern(""); } }?
Jesse C. Slicer

Jawaban:


55

Saya hanya dapat berasumsi di sini:

string.Emptytelah didefinisikan sebagai saksi - ketika menginisialisasi string, mungkin tidak jelas dari konteks yang ""memang secara eksplisit dimaksudkan sebagai inisialisasi (bukan nullatau katakan " "atau hanya sebagai tempat tempat selama pengujian). Menggunakan string.Emptyadalah jawaban yang pasti untuk teka-teki semacam itu.

Ini juga bisa menjadi throwback ke C - string kosong di C bukan string kosong. Ini adalah array karakter yang karakter pertamanya adalah null (karenanya, kosong), yang tidak sama dengan C #. Maksud saya di sini adalah bahwa dalam bahasa yang berbeda Anda akan mewakili string kosong dengan cara yang berbeda (dan mereka mungkin memiliki arti yang berbeda) - memiliki string.Emptymenghalangi ambiguitas tersebut.

Berbeda dengan apa yang orang lain katakan tentang banyak objek - ini bukan masalah karena string literal apa pun akan diinternir pada kompilasi. Ini termasuk nilai string.Empty- "". Setiap kali salah satu dari ini diulang dalam kode, objek akan diambil dari kolam magang. Ini benar per domain aplikasi .


5
+1 untuk menjadi satu-satunya jawaban yang benar sejauh ini.
psr

Beberapa bahasa bahkan mungkin tidak memiliki string literal kosong. Rupanya, Pascal standar tidak.
dan04

2
"string kosong dalam C bukan string kosong" - tapi tetap saja, jika Anda menulis "", Anda dapatkan {'\0'}, jadi tidak akan ada perbedaan antara string kosong literal dan beberapa cara bundaran lain untuk mendefinisikannya.
Detly

14

Saya tidak 100% yakin dengan sumber di mana saya mempelajari ini, tetapi beberapa poin untuk menggunakannya termasuk:

  • Setiap string dalam rakitan .NET unik, sehingga memiliki

    string foo = "";
    string bar = "";

    menghasilkan 2 string dalam rakitan output karena string tidak dapat diubah. Memiliki kedua referensi string.Emptymengurangi ukuran rakitan.

  • Kegamblangan. Ketika Anda menemukan string.Emptymaksudnya jelas bahwa itu seharusnya menjadi string kosong. Tetapi jika Anda menemukan foo = ""apakah programmer menghapus konten string saat pengujian dan lupa untuk menambahkannya kembali, atau apakah itu seharusnya seperti itu?

1
Tampaknya akan menjadi perilaku aneh untuk menyimpan dua string identik dalam ingatan. Apakah itu sebenarnya yang dilakukan?
Rig

36
Bahkan, yang terjadi adalah sebaliknya - ini disebut string interning (lebih tepatnya, interning literal). Saya tahu pasti itu dilakukan dalam Java dan Python, dan saya cukup yakin itu terjadi dalam bahasa .NET juga. Tentu saja, itu hanya dapat terjadi pada lingkup unit terjemahan tunggal, jadi kecuali jika loader dinamis menyatukan data seperti itu, Anda mungkin berakhir dengan satu string kosong per file program. Masih tidak terlalu banyak.

9
@nannan benar sekali. ""Saya string.Emptydiinternir dan hanya satu objek yang akan dibuat.
Oded

11
@Andy - Semua string literal diinternir dalam .NET. Tidak semua string. String yang dibuat secara programatik tidak diinternir secara default. Lihat String.Intern di MSDN.
Oded

3
@Oded et alia: Sebenarnya tidak ada di antara kalian yang benar. Pertama, literal diinternir dalam suatu majelis tetapi tidak harus di seluruh majelis . Kedua, apakah string kosong diinternir di seluruh majelis adalah detail implementasi; beberapa versi CLR lakukan dan beberapa tidak. Ada tautan ke artikel saya tentang fakta ini di salah satu jawaban lain; lihat detailnya.
Eric Lippert

2

Tidak ada objek yang akan dibuat string.Empty. Menggunakan ""akan membuat objek yang kemungkinan besar akan datang dari kolam string intern.

Di masa lalu, orang telah menjalankan tes dan String.Emptykeluar sedikit lebih cepat, tetapi ini adalah optimasi mikro.

String.Empty adalah ini:

//The Empty constant holds the empty string value.   
//We need to call the String constructor so that the compiler doesn't mark 
//this as a literal.   
//Marking this as a literal would mean that it doesn't show up as a field 
//which we can access from native.  
public static readonly String Empty = ""; 

2
Jadi maksud Anda adalah ...?

1
Intinya adalah String.Empty pada dasarnya adalah konstanta untuk "". Temukan penulis String.cs untuk makna yang lebih dalam. :)
Jon Raynor

0

Ini adalah masalah optimasi konsumsi memori dan optimasi perbandingan string. Setiap kali Anda menggunakan string kosong di aplikasi Anda, Anda mengalokasikan objek string yang berisi 0 karakter. Adapun perbandingan string dapat dilakukan dengan membandingkan referensi (pointer) daripada karakter dengan karakter, yang lebih cepat bahkan untuk string kosong.

Jika Anda menggunakan berkali-kali string yang sama dalam aplikasi Anda, Anda dapat menggunakan mekanisme yang sama dengan memanggil String.Intern () dengan string Anda. Tetapi jika Anda menggunakan setiap string hanya sekali, maka Anda hanya akan menggunakan lebih banyak memori.

Jadi String.Empty hanya optimasi kasus khusus yang layak dilakukan untuk sebagian besar aplikasi Net, itu sebabnya itu terintegrasi dalam BCL.

Untuk detail lebih lanjut tentang hal ini saya sangat merekomendasikan membaca posting blog Eric Lippert .

Anda juga harus melihat dokumentasi ini yang dirujuk oleh posting blog-nya.


4
Hanya tautan jawaban yang tidak menghasilkan jawaban yang baik. Jika Eric pernah mengatur ulang blognya, jawaban ini akan menjadi tidak berguna. Silakan rangkum posting di sini sehingga kami memiliki semua informasi yang bisa diberikan.
ChrisF

7
@ ChrisF: Saya tidak pernah bisa mengatur ulang blog. Itu akan menjadi perubahan yang menghancurkan, dan Anda tahu bagaimana perasaan saya tentang itu.
Eric Lippert

1
@EricLippert - Saya menyadari bahwa Anda tidak akan pernah melakukan itu, namun, hanya tautan jawaban yang bukan jawaban yang baik dan kami perlu mendorong orang untuk menyadarinya.
ChrisF

3
@EricLippert Ini bukan hanya tentang tautan singkat. Ini juga tentang kesopanan untuk pembaca di sini, harus ada setidaknya konten yang cukup langsung dalam jawaban sehingga pembaca dapat membentuk pendapat apakah akan mengikuti tautan. Dan jawabannya harus masuk akal bahkan dalam salinan offline SE.
Gilles 'SANGAT berhenti menjadi jahat'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.