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?

IamDeveloper
sumber
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.

Tomas Vana
sumber
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 Bezzub
sumber
@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)

Paul
sumber
5

Saya tahu, lama setelah itu relevan, tapi ... Saya curiga itu karena untuk jenis nullable seperti int? metode .ToString () tidak memungkinkan Anda untuk menggunakan format string. Lihat Bagaimana saya bisa memformat DateTime yang dapat dibatalkan dengan ToString ()? . Mungkin dalam kode asli, ada format string dalam. ToString (), atau mungkin kode lupa .ToString () tanpa format string masih tersedia pada tipe nullable.

outis nihil
sumber
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
Andrey
sumber
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.
}
Aliaksei Maniuk
sumber