Sıfırlanabilir ToString ()


142

Her yerde inşaat gibi görüyorum:

int? myVar = null;
string test = myVar.HasValue ? myVar.Value.ToString() : string.Empty;

Neden sadece kullanmıyorsunuz:

string test = myVar.ToString();

Tam olarak aynı değil mi? En azından Reflector şunları söylüyor:

public override string ToString()
{
  if (!this.HasValue)
  {
    return "";
  }
  return this.value.ToString();
}

Peki, bu doğru mu (daha kısa versiyon) mı yoksa bir şey mi kaçırıyorum?


1
Böyle bir kod görmedim :)
timtam

Yanıtlar:


112

Çok haklısın. Ayrıca bu soruda , eski çözüm öneriliyorken, aslında kimse fark etmiyor ToString()zaten doğru cevabı veriyor.

Belki daha ayrıntılı çözüm için argüman okunabilirliğin: Aradığınızda ToString()olan şey gerekiyordu olmak null, genellikle bekliyoruz bir NullReferenceExceptiono atılır değil burada olsa.


21
Aslında, en az iki kişi fark etti: Eric Lippert ve Johannes Rössel.
Jon Skeet

7
Kastettiğinizin bu olmadığından emin olmakla birlikte, referans burada aslında boş değil. Sıfırlanabilir <T> bir değer türüdür. Bu yüzden arama ToString()herhangi bir NullReferenceExceptionşey yapılmadan çalışır .
Thorarin

2
Eğer bu düşünce tarzı olsaydı .HasValue, yine de istisnayı atmayı beklersiniz .
Extragorey

Kullanıcıların ayrıntılı sürümü kullanmasının bir başka nedeni myNullableDateTime.HasValue ? myNullableDateTime.Value.ToString("d") : null, istenen ToStringyönteme erişmek için kaydırılmamış nesneye ihtiyacınız olduğu gibi ifadelerle eşitlik olabilir . Tabii ki, bunun için daha özlü bir çözüm var:$"{myNullableDateTime:d}"
Extragorey

14

Birçok insanın böyle kontrolleri olduğunu düşünüyorum çünkü null değerini tutabilecek bir nesnenin doğal davranışı değil.


@Andrew, kabul etti, çünkü insanlar (benim gibi) ilk başta bunun bir istisna atacağını düşünüyorlar.
Nathan Koop

1
Bunun davranış olduğunu bilmiyordum. Kesinlikle x.ToString () çağırırsanız (x == null) için true döndüren herhangi bir yapı da bir NullReferenceException atmak düşünürdüm.
Dan Bryant

5

Hayır, haklısın, daha kısa versiyon bu konuda diğer insanların yaptıklarıyla aynı. Nullables ile üçlü yerine çok kullanma eğiliminde olduğum diğer yapı, boş birleştirme operatörüdür. bu da sizi sıfırlardan korur. ToString () için (işaret ettiğiniz gibi) gerekli değildir, ancak varsayılan int değerleri için (örneğin) güzel çalışır, örneğin:

int page = currentPage ?? 1;

sayfadaki tüm tamsayı işlemlerini ilk olarak açıkça null denetimi ve currentPage'deki değeri çağırmanızı sağlar (burada currentPage bir int? belki de bir param olarak iletilir)


5

Biliyorum, konuyla ilgilendikten çok sonra, ama ... Bunun int gibi null olabilecek türler için olduğundan şüpheleniyorum. .ToString () yöntemi biçim dizelerini kullanmanıza izin vermez. Bkz. Null olabilecek bir DateTime'ı ToString () ile nasıl biçimlendirebilirim? . Belki de orijinal kodda .ToString () içinde bir biçim dizesi vardı ya da kodlayıcı, biçim dizesi olmadan .ToString () işlevinin nullable tiplerinde hala kullanılabilir olduğunu unutmuştu.


3

olabilir sadece desen takip etmek? ya da arka ucu bilmiyorlar. doğru kod tam olarak aynı. hatta şunları yapabilirsiniz:

int? i = null;
i.ToString(); //No NullReferenceException

ToString () değişken olmayan bir kültüre ihtiyaç duyarsa, uzun yoldan gitmeniz gerekebilir, çünkü nullables kendi menüsünde yok.
13:02

1

int?null değişken değişkenin bildirimini basitleştiren sözdizimi şekeri. İle aynıdır Nullable<int>.

Dolayısıyla, ToString()yöntemin uygulanmasına Nullable<T> (aşağıya bakın) bakarsanız, değerinin olmadığı durumlarda boş dize döndürdüğünü fark edebilirsiniz.

public struct Nullable<T> where T : struct
{
    public override string ToString()
    {
      if (!this.hasValue)
        return "";
      return this.value.ToString();
    }
}

MSDN ne diyor:

Nullable.ToString Yöntemi

HasValue özelliği true olduğunda geçerli Nullable nesnesinin değerinin metin temsilini veya HasValue özelliği false olursa boş bir dize ("") döndürür.

Bu nedenle, aşağıdaki kod ArgumentNullExceptionistisna atmak yerine konsola boş dize yazdırır .

static void Main(string[] args)
{
    int? a = null;
    Console.WriteLine(a.ToString()); // Prints empty string to console.
}
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.