Saya melakukan riset tentang hal ini dengan menggunakan metode yang berbeda untuk menetapkan nilai ke int nullable. Inilah yang terjadi ketika saya melakukan berbagai hal. Harus menjelaskan apa yang terjadi. Perlu diingat: Nullable<something>
atau steno something?
adalah struct yang tampaknya dikompilasi oleh banyak kompiler agar kita gunakan dengan null seolah-olah itu adalah kelas.
Seperti yang akan Anda lihat di bawah, SomeNullable == null
dan SomeNullable.HasValue
akan selalu mengembalikan yang diharapkan benar atau salah. Meskipun tidak diperlihatkan di bawah, SomeNullable == 3
valid juga (dengan asumsi SomeNullable adalah an int?
).
Sementara SomeNullable.Value
membuat kita error jika kita ditugaskan null
untuk SomeNullable
. Ini sebenarnya satu-satunya kasus di mana nullables dapat menyebabkan masalah bagi kami, berkat kombinasi operator yang kelebihan beban, kelebihan muatanobject.Equals(obj)
metode, dan optimisasi kompiler dan bisnis monyet.
Berikut ini adalah deskripsi dari beberapa kode yang saya jalankan, dan output apa yang dihasilkan oleh label:
int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Oke, mari kita coba metode inisialisasi selanjutnya:
int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Semua sama seperti sebelumnya. Perlu diingat bahwa menginisialisasi dengan int? val = new int?(null);
, dengan null yang diteruskan ke konstruktor, akan menghasilkan kesalahan waktu COMPILE, karena VALUE objek yang dapat dibatalkan TIDAK BISA nullable. Hanya objek pembungkus itu sendiri yang bisa sama dengan nol.
Demikian juga, kami akan mendapatkan kesalahan waktu kompilasi dari:
int? val = new int?();
val.Value = null;
belum lagi itu val.Value
adalah properti baca-saja, artinya kita bahkan tidak bisa menggunakan sesuatu seperti:
val.Value = 3;
tetapi sekali lagi, operator konversi implisit berlebih polimorf mari kita lakukan:
val = 3;
Tidak perlu khawatir tentang polisom apa pun yang bisa menahan, asalkan berfungsi dengan benar? :)