String.Empty özelliğinin amacı nedir


35

Emlak neden string foo = string.EmptyBCL'ye dahil edildi? Boş bir dize ( string foo = "") kullanmaktan daha ayrıntılı ve net görünmüyor


6
Nitpick: Bu dilin bir parçası değil. BCL'nin bir parçasıdır. VB.NET ve F #, diğer tüm .NET dillerinin yanı sıra bunu kullanabilir.
Oded

19
Çünkü aksi takdirde, kötü şeyler yapamazdın typeof(string).GetField("Empty").SetValue(null, " ");;)
Mason Wheeler

1
@MasonWheeler - Yansıma sevinçleri. Gerçek kötülük için iç gözlemine ihtiyacın var, ha?
Oded

1
@MasonWheeler, +1. Aman tanrım, gözlükler, hiçbir şey yapmazlar!]
Machado

1
@MasonWheeler Saf, saf damıtılmış şeytan. Bunu seviyorum. İlgileniyorsanız soru: olarak yazmak daha güvenli (ve terbiyeli performansta) olmaz mıydı public static string Empty { get { return string.Intern(""); } }?
Jesse C. Dilimleme

Yanıtlar:


55

Sadece burada varsayabilirim:

string.Emptyaçıklık için tanımlanmıştır - bir dize başlatılırken, ""açıkça bir başlatıcı olarak ifade edilen bağlamdan net bir şekilde anlaşılamıyor olabilir (yerine nullveya söylemek " "veya sadece test sırasında bir yer tutucu olarak). Kullanmak string.Empty, bu tür bir bilmeceye kesin bir cevaptır.

Aynı zamanda C'ye geri dönüş olabilir - C'deki boş bir dize boş bir dize değildir. İlk karakteri null (dolayısıyla boş) olan, C # ile aynı olmayan bir karakter dizisidir. Buradaki noktam, farklı dillerde boş bir dizgiyi farklı şekillerde (ve farklı anlamlara sahip olabilir) temsil edersiniz - string.Emptyböyle bir belirsizliği engeller.

Başkalarının çoklu nesneler hakkında söylediklerinin aksine - bu herhangi bir string değişmezi derlemeye gireceği için bir problem değildir. Bu, string.Empty- değerini içerir "". Bunlardan herhangi biri kodda tekrarlandığında, nesne stajyer havuzundan alınacaktır. Bu, uygulama alanı başına geçerlidir .


5
Şimdiye kadar doğru tek cevap olduğu için +1.
psr

Bazı diller bile olmayabilir sahip boş bir dize. Görünüşe göre standart Pascal yoktu.
dan04,

2
"C'deki boş bir dize boş bir dize değildir" - ancak yine de yazarsanız "", anlarsınız {'\0'}, bu nedenle boş bir dize değişmezi ile onu tanımlamanın başka bir dolambaçlı yolu arasında bir fark olmazdı.
Ocak'ta

14

Bunları öğrendiğim kaynaklardan% 100 emin değilim, ancak onu kullanmanın bazı noktaları:

  • .NET derlemesindeki her dize benzersizdir,

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

    Dizeler değişmez olduğu için çıktı dizisinde 2 dizge ile sonuçlanır. Her iki referansa sahip olmak string.Emptymontaj boyutunu azaltır.

  • Anlaşılırlık. Niyete rastladığınızda string.Empty, boş bir dize olması gerektiği açık. Ancak foo = ""rastlarsanız, programcı test sırasında dizginin içeriğini kaldırmış ve geri eklemeyi unutmuş, yoksa bu şekilde mi olması gerekiyor?

1
İki özdeş diziyi bellekte tutması tuhaf bir davranış gibi görünüyor. Aslında bu ne yapılır?
Rig

36
Aslında, bunun tersi yapılır - string interning (daha doğrusu değişmezlerin interning'i). Java ve Python'da yapıldığından emin olduğumu biliyorum ve .NET dillerinde de böyle olduğuna eminim. Elbette, yalnızca tek bir çeviri birimi kapsamında gerçekleşebilir, bu nedenle dinamik yükleyici bu verileri birleştirmediği sürece, program dosyası başına bir boş dize ile sonuçlanabilir. Hala çok fazla değil.

9
@delnan kesinlikle haklı. ""/ string.Emptyinterned ve yalnızca bir nesne oluşturulacak.
Oded

11
@Andy - Tüm string değişmezleri .NET'te bulunur. Tüm dizeler değil . Programatik olarak oluşturulan dizeler varsayılan olarak internet alınmaz. MSDN'deki String.Intern'a bakın .
Oded

3
@Oded et alia: Aslında hiçbiriniz haklı değilsiniz. İlk olarak, değişmezler bir meclis içerisinde yer alır, ancak meclisler arasında zorunlu değildir . İkincisi, boş dizgenin meclisler arasında yer alıp almadığı bir uygulama detayıdır; CLR’nin bazı sürümleri Bu konuda yazdığım makalenin bir başka cevabı var; Ayrıntılar için bakın.
Eric Lippert

2

İçin hiçbir nesne oluşturulmayacak string.Empty. Kullanmak "", büyük olasılıkla string intern havuzundan gelecek bir nesne yaratacaktır.

Geçmişte, insanlar testler yaptılar ve String.Emptybiraz daha hızlı çıktılar, ancak bu bir mikro-optimizasyon.

String.Empty şudur:

//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
Demek istediğin ...?

1
Nokta String.Empty temelde "" için bir sabittir. Daha derin bir anlam için String.cs'in yazarını bulun. :)
Jon Raynor,

0

Bu, bellek tüketiminin optimizasyonu ve dizi karşılaştırmasının optimizasyonu konusudur. Uygulamanızda her zaman boş bir dize kullandığınızda, 0 karakter içeren bir dize nesnesi tahsis ediyorsunuz. Dizi karşılaştırmasında, karakter dizisi yerine referanslar (işaretçiler) karakterlerle karşılaştırılarak yapılabilir, bu boş karakter dizileri için bile daha hızlıdır.

Uygulamanızda aynı dizeyi defalarca kullanıyorsanız, dizenizle birlikte String.Intern () yöntemini çağırarak aynı mekanizmayı kullanabilirsiniz. Ancak her dizeyi yalnızca bir kez kullanıyorsanız, yalnızca daha fazla bellek kullanırsınız.

Yani String.Empty sadece çoğu .Net uygulaması için yapmaya değer özel bir durum optimizasyonudur, bu yüzden BCL'ye entegre edilmiştir.

Bu konuda daha fazla ayrıntı için, Eric Lippert'in blog yazısını okumanızı şiddetle tavsiye ediyorum .

Blog postasının referans aldığı bu belgelere de bir göz atmalısınız .


4
Link sadece cevaplar iyi cevaplar yapmaz. Eric blogunu yeniden düzenlerse, bu cevap işe yaramaz hale gelir. Lütfen buradaki yazıyı özetleyiniz , böylece elimizdeki tüm bilgilere sahip olabiliriz.
ChrisF

7
@ChrisF: Blogu hiçbir zaman yeniden düzenleyemiyorum. Bu çok büyük bir değişiklik olur ve sen de onlar hakkında ne hissettiğimi biliyorsun.
Eric Lippert

1
@EricLippert - Farkındayım sen ediyorum ancak, bağlantı sadece cevaplar iyi cevaplar değildir ve biz fark etmeye teşvik etmek gerek, bunu yapma.
ChrisF

3
@EricLippert Sadece geçici bağlantılar değil. Aynı zamanda buradaki okurlara nezaketle ilgili, en azından doğrudan cevapta yeterince içerik bulunmalı, böylece okuyucular bağlantıyı takip edip etmeyeceklerine dair bir fikir oluşturabilsin. Ve cevap SE'nin çevrimdışı bir kopyasında bile mantıklı olmalı.
Gilles 'SO- kötülük olmayı'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.