Nullable ToString ()


142

Saya melihat konstruksi di mana-mana seperti:

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

Mengapa tidak menggunakan:

string test = myVar.ToString();

Bukankah itu persis sama? Setidaknya Reflector mengatakan bahwa:

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

Jadi, apakah itu benar (versi yang lebih pendek) atau apakah saya kehilangan sesuatu?


1
Saya belum melihat kode seperti ini :)
tymtam

Jawaban:


112

Anda benar sekali. Juga dalam pertanyaan ini , solusi pertama disarankan sementara tidak ada yang benar-benar memperhatikan ToString()sudah memberikan jawaban yang benar.

Mungkin argumen untuk solusi yang lebih verbose adalah pembacaan: Ketika Anda menelepon ToString()pada sesuatu yang seharusnya menjadi null, Anda biasanya mengharapkan sebuah NullReferenceException, walaupun di sini tidak dibuang.


21
Sebenarnya, setidaknya dua orang memperhatikan: Eric Lippert dan Johannes Rössel.
Jon Skeet

7
Meskipun saya yakin bukan itu yang Anda maksudkan, rujukannya sebenarnya tidak nol di sini. Nullable <T> adalah tipe nilai. Inilah sebabnya mengapa panggilan ToString()berhasil tanpa NullReferenceExceptiondilemparkan.
Thorarin

2
Jika itu adalah mentalitasnya, Anda .HasValuemasih berharap untuk membuang pengecualian itu.
Luar Biasa

Alasan lain mengapa orang menggunakan versi verbose mungkin adalah untuk paritas dengan ekspresi seperti di myNullableDateTime.HasValue ? myNullableDateTime.Value.ToString("d") : nullmana Anda memerlukan objek yang terbuka untuk mengakses ToStringmetode yang diinginkan . Tentu saja, ada solusi yang lebih ringkas untuk itu juga:$"{myNullableDateTime:d}"
Extragorey

14

Saya pikir banyak orang memiliki pemeriksaan seperti itu karena itu bukan perilaku alami dari suatu objek yang dapat memiliki nilai nol.


@Andrew, setuju, karena orang-orang (seperti saya) pada awalnya berpikir bahwa itu akan melempar pengecualian.
Nathan Koop

1
Saya tidak tahu ini adalah perilaku. Saya pasti akan berpikir bahwa setiap konstruk yang mengembalikan true untuk (x == null) juga akan melempar NullReferenceException jika Anda memanggil x.ToString ().
Dan Bryant

5

Tidak, Anda benar, versi yang lebih pendek sama dengan apa yang dilakukan orang lain dalam hal itu. Konstruk lain yang cenderung saya gunakan banyak daripada terner dengan nullables adalah operator penggabungan nol. yang juga melindungi Anda dari nol. Untuk ToString () itu tidak perlu (seperti yang Anda tunjukkan) tetapi untuk nilai int default (misalnya) itu berfungsi dengan baik, misalnya:

int page = currentPage ?? 1;

yang memungkinkan Anda melakukan semua operasi bilangan bulat di halaman tanpa pertama-tama secara eksplisit membatalkan dan memanggil nilai dalam currentPage (di mana currentPage adalah int? mungkin disahkan sebagai param)



3

mungkin itu hanya mengikuti pola? atau mereka tidak tahu backend. kode Anda benar persis sama. Anda bahkan dapat melakukannya:

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

Anda mungkin perlu mengambil rute panjang jika ToString () harus dari budaya invarian, karena nullables tidak memilikinya di menu mereka.
Ε Г И І И О

1

int?adalah sintaksis gula yang menyederhanakan deklarasi variabel nullable. Itu sama dengan Nullable<int>.

Jadi jika Anda melihat implementasi ToString()metode untuk Nullable<T> (lihat di bawah) , Anda dapat melihat, bahwa ia mengembalikan string kosong jika tidak memiliki nilai.

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

Apa yang dikatakan MSDN:

Metode Nullable.ToString

Mengembalikan representasi teks dari nilai objek Nullable saat ini jika properti HasValue benar, atau string kosong ("") jika properti HasValue salah.

Jadi kode berikut akan mencetak string kosong ke konsol alih-alih melempar ArgumentNullExceptionpengecualian.

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