String.Empty, isteğe bağlı bir parametre için varsayılan değer olarak kullanılamaz


89

Bill Wagner'den Etkili C # okuyorum . In Madde 14 - Yinelenen Başlatma Mantık Minimize , o yeni opsiyonel parametreler yapıcı özelliğini kullanarak aşağıdaki örnek gösterir:

public MyClass(int initialCount = 0, string name = "")

Onun ""yerine kullandığına dikkat edin string.Empty.
O şöyle yorumluyor:

[Yukarıdaki bir örnekte], ikinci yapıcının daha alışılmış olan yerine , ad parametresindeki varsayılan değer için "" belirttiğine dikkat edin string.Empty. Bunun nedeni string.Empty, derleme zamanı sabiti olmamasıdır. String sınıfında tanımlanan statik bir özelliktir. Derleme sabiti olmadığından, onu bir parametrenin varsayılan değeri için kullanamazsınız.

string.EmptyStatiği her durumda kullanamazsak, bu onun amacını bozmaz mı? Boş dizgeye atıfta bulunmak için sistemden bağımsız bir yolumuz olduğundan emin olmak için kullanacağımızı düşündüm. Anlayışım yanlış mı? Teşekkürler.

GÜNCELLEME
Sadece bir takip yorumu. MSDN'ye göre:

Her isteğe bağlı parametrenin tanımının bir parçası olarak varsayılan bir değeri vardır. Bu parametre için hiçbir bağımsız değişken gönderilmezse, varsayılan değer kullanılır. Varsayılan değerler sabit olmalıdır.

O zaman System.Environment.NewLineikisini de kullanamayız veya yeni örneklenmiş nesneleri varsayılan değerler olarak kullanamayız. Henüz VS2010 kullanmadım ve bu hayal kırıklığı yaratıyor!


2
Boş dizelerin farklı platformlarda nasıl temsil edildiği arasında herhangi bir farkın farkında değilim. Newline gibi değil.
Tom Cabanski

Doğru, bunu düşünüyordum, o zaman sadece kodda daha güzel görünüyor mu?
Mikeyg36

1
"" Boş bir dizge olup olmadığı konusunda belirleyici faktör, 'Sistem' değil CLR'dir. Bu nedenle, "" uyumlu bir CLR uygulamasında bir dizeye atıfta bulunmanın sistemden bağımsız bir yolu olduğunu güvenle varsayabileceğinizi düşünüyorum.
Chris Taylor

"sistemden bağımsız" mı? er, sisteme özgü "" yerine? (???)
Qwertie

MSDN'ye göre: Bu alanın değeri "" sıfır uzunluklu dizedir. Bu nedenle, birçok insanın işaret ettiği gibi, bunun platform bağımsızlığıyla hiçbir ilgisi olmadığı açıktır. Yine de insanlar neden kullanılması gerektiğini gerçekten bilmiyor gibi görünüyor!
Mikeyg36

Yanıtlar:


66

C # 2.0 derleyicisinden itibaren, String.Emptyyine de çok az nokta var ve aslında çoğu durumda bu bir karamsarlıktır, çünkü derleyici bazı referansları satır içinde ""yapabilir ancak aynı şeyi yapamaz String.Empty.

C # 1.1'de, tümü boş dizgiyi içeren çok sayıda bağımsız nesne oluşturmaktan kaçınmak yararlıydı, ancak o günler geride kaldı. ""gayet iyi çalışıyor.


7
.NET 1.1'de bile "çok sayıda" bağımsız nesne yaratmaz. Bu açıdan 1.1 ve 2.0 arasındaki farkların ayrıntılarını hatırlayamıyorum, ancak dizgi literal interning sadece 2.0'da tanıtılmış gibi değil.
Jon Skeet

Açıklama için teşekkürler. Etrafa bir göz attım ve C # 2.0'daki değişikliklerin iyi bir özetini bulamadım, ancak daha önce bir tane okuduğuma eminim. 2008'den itibaren daha fazla teknik bilgi için bazı bağlantılar içeren bir StackOverflow cevabı buldum. stackoverflow.com/questions/151472/…
Andy Mortimer

1
Buna bir baş sallayacağım, ancak ipin çok az anlamı olduğunu söylemekten hoşlanmıyorum, oldukça yoğun kullandığım için boş. Kişisel görüşüm olmasına rağmen, daha temiz göründüğünü görüyorum. String.Empty kullanılamayacak birçok yer var ve bu durumlarda "" kullanmakta sorun
yaşamıyorum

15
String.Empty ile boş bir dizeyi hızlı bir şekilde tanımlamanın, içinde kesme işareti veya buna benzer bir şey olmadığından emin olmak için "" öğesine iki kez bakmaktan çok daha kolay olduğunu buldum. Yine de açıklama için +1.
NotMe

11
+1 Chris. Ayrıca VS'de, "" kullanımlarında gerçekten bir arama yapamazsınız (yorumlar ve işaretleme dahil her metin eşleşmesini de geri getirecek olan standart Bul'u yapmak dışında). String.Empty ile koda özgü kullanımlarda arama yapabilirsiniz.
MutantNinjaCodeMonkey

53

Opsiyonel bir parametre değeri olarak gerçekten kullanmak istiyorsanız, boş dize için kendi sabitinizi tanımlamanıza engel olacak hiçbir şey yoktur:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[Bir kenara, diğer cevaplarda belirtilmeyen genel olarak tercih String.Emptyedilmesinin bir nedeni "", çıplak gözle görülemeyen çeşitli Unicode karakterlerinin (sıfır genişlikli birleştiriciler, vb.) Olmasıdır. Yani benzeyen bir şey ""mutlaka boş dizge değildir, oysa sizle String.Emptytam olarak ne kullandığınızı bilirsiniz. Bunun yaygın bir hata kaynağı olmadığını biliyorum, ancak bu mümkün.]


2
Ayrıca görünmez tanımlayıcı karakterler de vardır, bu nedenle String_Empty gibi görünen bir şey mutlaka olması gerekmez. Unicode standardı, güvenlik hususlarıyla ilgili büyük ölçüde göz ardı edilen bir bölüme sahiptir.
Jim Balter

25

Orijinal sorudan:

Boş dizgeye atıfta bulunmak için sistemden bağımsız bir yolumuz olduğundan emin olmak için kullanacağımızı düşündüm.

Boş dizge sistemden sisteme ne şekilde değişebilir? Her zaman karakter içermeyen bir dizedir! Ben olurdum gerçekten şimdiye kadar bir uygulama bulursa korkmuş string.Empty == ""yanlış döndü :) Bu değil gibi bir şey aynı Environment.NewLine.

Terörle Mücadele'nin ödül gönderisinden:

String.Empty'nin bir sonraki C # sürümünde varsayılan parametre olarak kullanılabilmesini istiyorum. : D

Bu kesinlikle olmayacak.

Kişisel olarak çok farklı bir varsayılan mekanizmayı da sevmiş olsam da, isteğe bağlı parametrelerin çalışma şekli başlangıçtan beri .NET'te olmuştur - ve bu her zaman meta verilere bir sabit yerleştirmek anlamına gelir, böylece çağıran kod bu sabiti çağrıya kopyalayabilir ilgili bağımsız değişken sağlanmadıysa site.

İle string.Emptybu kadar gerçekten anlamsız - kullanarak ""istediğini yapacak; Dizgiyi değişmez kullanmak o kadar acı verici mi? (Kelimenin tam anlamıyla her yerde kullanırım string.Empty- asla kullanmam - ama bu farklı bir argüman.)

Bu soru hakkında beni şaşırtan neydi o en - şey etrafında şikayet döndürülür böylece değil gerçek bir sorun nedeni aslında. Varsayılanın yürütme sırasında hesaplanmasını istediğiniz durumlarda daha önemlidir, çünkü aslında değişebilir. Örneğin, bir DateTimeparametresi olan bir yöntemi çağırıp varsayılan olarak "geçerli zamana" sahip olmasını istediğiniz durumları hayal edebilirim . Şu anda bunun için bildiğim belli belirsiz zarif çözüm şudur:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... ama bu her zaman uygun değildir.

Sonuç olarak:

  • Bunun C'nin bir parçası olacağından çok şüpheliyim
  • İçin string.Empty's anlamsız oldu Neyse
  • Gerçekten her zaman aynı değere sahip olmayan diğer değerler için gerçekten acı verici olabilir .

Bu aslında sorunu çözmenin iyi bir yoludur. Aynı şey, diğer cihaza bağlı değişkenleri taşımak / ayarlamak için de kullanılabilir. Örneğinizde Environment.Newlineeksik olan tek şey, değişkenin null için kontrol edilmesi ve geliştiriciye ona boş değer atanabilirken bunun olduğunu söyleyen bir istisna atmak olacaktır. kabul edilmedi. if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");}ya da böyle bir şey. Ama bundan gerçekten hoşlanıyorum! Kendi yönteminizle yapmanız için başka bir uyarı var mı?
MaxOvrdrv

@MaxOvrdrv: Bunun bir hata olmasını istemezsiniz - bütün mesele şu ki, boş olduğunda, bir varsayılan hesaplarsınız. Uyarı, boş değerin kendi içinde geçerli bir değer olarak geçirilmesine izin vermemesidir.
Jon Skeet

Bu konuda tamamen haklısın. Benim hatam. - Ve evet, tek gerçek uyarı bu olurdu değil mi ... bu çok da kötü değil. Yine: Bu çözümü gerçekten beğendim! :) Gönderdiğiniz için teşekkürler! :)
MaxOvrdrv

7

String.Empty'yi asla kullanmıyorum, anlamını göremiyorum. Belki programlama konusunda gerçekten yeni olan insanlar için işi kolaylaştırır, ancak bunun için bile yararlı olduğundan şüpheliyim.


2
Belki kafa karıştırmayı önler ""ve " "ama bunun " "bu kadar yaygın olduğunu söyleyemem .
Greg

8
Bu ihtiyaçları ya daha iyi gözlükler arasındaki farkı anlayamayan ya da ekranlarının çözünürlüğünü düşürmelerini öneriyorum. Görüşüm kötü ve bu hatayı yaptığımı hatırlayamıyorum (ve her ikisini de içeren çok sayıda kodla çalışmam gerekiyor).
Hans Olsson

2
string.Empty, programcının tam niyetini bulmak için kullanışlıdır. "" niyet hakkında hiçbir şey söylemez, ya programcının niyeti bu "lol" gibi değişkeni başlatmaksa ama unutmuşsa ... bu durumda sonsuz olasılıklar ve dizge vardır, Boş işe
yarar

4

String.Empty'nin arkasındaki fikir, okunabilirliği arttırması olduğunu düşünüyorum. Farklı platformlarda temsil edilme biçimleri arasında herhangi bir farkın olduğu yeni satır gibi değildir. Varsayılan bir parametrede kullanılamaması utanç verici. Ancak, Windows ile Linux'ta Mono gibi bir şey arasında bağlantı kurarsanız herhangi bir soruna neden olmaz.


5
Sanırım önemli olan nokta, bazı insanların String.Emptydaha okunabilir olduğunu düşündüğü konusunda muhtemelen haklısınız . . . şahsen bunun biraz çılgınca olduğunu düşünüyorum. ""Muhtemelen en yaygın dizedir ve herkes onu milyarlarca kez görmüş, öyleyse nasıl okunamaz? String.Emptybir Int32.Zero.
Tim Goodman

3

Bir FYI olarak, öznitelik oluşturuculara aktarılan değerlere aynı kısıtlama uygulanıyor gibi görünüyor - bunlar sabit olmalıdır. String.empty şu şekilde tanımlandığından:

public static readonly string Empty

gerçek bir sabit yerine kullanılamaz.


2

string.EmptyTamamen okunabilirlik için kullanıyorum .

Bir başkasının kodumu daha sonra okuması / değiştirmesi gerekirse, kontrol etmek ya da boş bir dizeye bir şey ayarlamak istediğimi bilirler. Sadece kullanmak ""bazen hatalara ve kafa karışıklığına neden olabilir çünkü istediğim dizeyi oraya koymayı unutmuş olabilirim.

Örneğin:

if(someString == string.Empty)
{

}

vs

if(someString == "")
{

}

İlk ififade bana çok daha bilinçli ve okunabilir görünüyor. Bu sadece bir tercih olduğu için, ""bunun yerine kullanmak zorunda kalmanın tren çarpışmasını gerçekten görmüyorum string.Empty.


-2

Belki de bu soruna en iyi çözüm, bu yöntemin şu şekilde aşırı yüklenmesidir:

public static void PrintString() 
{ 
    PrintString(string.Empty);
}

3
Yukarıdaki sorunun cevabı bu nasıl?
Pranav Singh

1
İsteğe bağlı parametreler için varsayılan değerlere nasıl yardımcı olur?
varsayılan yerel ayar
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.