Mengapa Convert.ToString (null) mengembalikan nilai yang berbeda jika Anda memasukkan null?

116
Convert.ToString(null)

kembali

null

Seperti yang kuharapkan.

Tapi

Convert.ToString(null as object)

kembali

""

Mengapa ini berbeda?

John MacIntyre
sumber

Jawaban:

143

Ada 2 kelebihan ToStringyang ikut bermain di sini

Convert.ToString(object o);
Convert.ToString(string s);

Kompiler C # pada dasarnya mencoba untuk memilih kelebihan beban paling spesifik yang akan bekerja dengan input. Sebuah nullnilai adalah konversi untuk semua jenis referensi. Dalam kasus stringini lebih spesifik daripada objectdan oleh karena itu akan dipilih sebagai pemenang.

Di bagian null as objectAnda telah memperkuat jenis ekspresi sebagai object. Ini berarti itu tidak lagi kompatibel dengan stringkelebihan beban dan kompilator mengambil objectkelebihan beban karena itu satu-satunya yang kompatibel yang tersisa.

Detail yang sangat detail tentang cara kerja pemutusan dasi ini tercakup dalam bagian 7.4.3 dari spesifikasi bahasa C #.

JaredPar
sumber
15
Baik. Jadi itu menggunakan satu kelebihan beban, bukan yang lain. Masuk akal. Tetapi bukankah kedua kelebihan beban harus mengembalikan hal yang sama? +1 btw.
John MacIntyre
2
@JohnMacIntyre - Itu tergantung pada tim pengembangan, bukan kompilernya.
JonH
8
@JohnMacIntyre Jika Anda melihat penerapannya, Convert.ToString(string)itu hanya fungsi identitas sementara Convert.ToString(object)sebenarnya melalui jalur yang lebih sulit untuk diikuti. Sekilas saya setuju mereka harus mengembalikan yang sama tetapi lapisan convertible BCL bukanlah sesuatu yang sangat saya ketahui dan mungkin ada alasan bagus untuk perbedaan tersebut (meskipun saya skeptis)
JaredPar
Saya datang ke sini mencari cara mengubah objek nol menjadi string nol. Jawaban untuk pencari lain adalah (string)null, atau jika objek Anda disebut o, maka(string)o
rayzinnz
65

Mengikuti dari jawaban resolusi kelebihan beban JaredPar yang sangat baik - pertanyaannya tetap "mengapa Convert.ToString(string)mengembalikan nol, tetapi Convert.ToString(object)mengembalikan string.Empty"?

Dan jawabannya adalah ... karena dokumen mengatakan demikian :

Convert.ToString (string) mengembalikan "contoh string yang ditentukan; tidak ada konversi aktual yang dilakukan."

Convert.ToString (object) mengembalikan "representasi string dari nilai, atau String.Empty jika nilainya null."

EDIT: Seperti apakah ini adalah "bug dalam spesifikasi", "desain API yang sangat buruk", "mengapa itu ditentukan seperti ini", dll. - Saya akan mencoba beberapa alasan mengapa saya tidak melihat itu masalah besar.

  1. System.Convertmemiliki metode untuk mengubah setiap tipe dasar menjadi dirinya sendiri . Ini aneh - karena tidak diperlukan atau mungkin konversi, jadi metode ini hanya mengembalikan parameter. Convert.ToString(string)berperilaku sama. Saya menganggap ini di sini untuk skenario pembuatan kode.
  2. Convert.ToString(object)memiliki 3 pilihan saat lulus null. Lempar, kembalikan null, atau kembalikan string. Melempar akan berakibat buruk - jadi dua kali lipat dengan asumsi ini digunakan untuk kode yang dihasilkan. Mengembalikan null mengharuskan pemanggil Anda melakukan pemeriksaan null - sekali lagi, bukan pilihan yang bagus dalam kode yang dihasilkan. Returning string. Kekosongan tampaknya merupakan pilihan yang masuk akal. Sisa System.Convertpenawaran dengan jenis nilai - yang memiliki nilai default.
  3. Masih bisa diperdebatkan apakah mengembalikan null lebih "benar", tetapi string.Empty jelas lebih bisa digunakan. Mengubah Convert.ToString(string)berarti melanggar aturan "tidak ada konversi yang sebenarnya". Karena System.Convertmerupakan kelas utilitas statis, setiap metode dapat diperlakukan secara logis sebagai miliknya sendiri. Ada sangat sedikit skenario dunia nyata di mana perilaku ini harus "mengejutkan", jadi biarkan kegunaan menang atas (kemungkinan) kebenaran.
Tandai Brackett
sumber
Apakah adil untuk mengatakan bahwa itu adalah bug dalam spesifikasi?
John MacIntyre
3
itu tidak menjawab mengapa seperti ini. Mengatakan itu berperilaku seperti ini karena itu didokumentasikan untuk berperilaku seperti ini adalah tautologis.
CodesInChaos
2
@JohnMacIntyre IMO adil untuk mengatakan bahwa itu adalah desain API yang sangat buruk.
CodesInChaos
7
@CodeInChaos - bukan tautologi, kecuali jika Anda menganggap dokumen ditulis berdasarkan perilaku yang dapat diamati setelah BCL dikembangkan. Itu akan menjadi asumsi yang aneh, saya pikir. IOW, itu tidak "didokumentasikan untuk berperilaku seperti ini", itu "didokumentasikan bahwa ia akan berperilaku seperti ini" - yaitu, " ditentukan untuk berperilaku seperti ini".
Mark Brackett
8
Ini hanya menggeser pertanyaan menjadi "mengapa itu ditentukan untuk berperilaku seperti ini"
CodesInChaos