Tôi đã thực hiện một số nghiên cứu về điều này bằng cách sử dụng các phương thức khác nhau để gán giá trị cho một int nullable. Đây là những gì đã xảy ra khi tôi làm nhiều việc khác nhau. Nên làm rõ những gì đang xảy ra. Hãy ghi nhớ: Nullable<something>
hoặc tốc ký something?
là một cấu trúc mà trình biên dịch dường như đang thực hiện rất nhiều công việc để cho chúng tôi sử dụng với null như thể nó là một lớp.
Như bạn sẽ thấy bên dưới, SomeNullable == null
và SomeNullable.HasValue
sẽ luôn trả về đúng hoặc sai dự kiến. Mặc dù không được trình bày dưới đây, nhưng SomeNullable == 3
cũng hợp lệ (giả sử someNullable là một int?
).
Trong khi SomeNullable.Value
chúng ta gặp lỗi thời gian chạy nếu chúng ta được gán null
cho SomeNullable
. Trên thực tế đây là trường hợp duy nhất mà nullables có thể gây ra sự cố cho chúng tôi, nhờ vào sự kết hợp của các toán tử quá tải, quá tảiobject.Equals(obj)
phương pháp, và tối ưu hóa trình biên dịch và kinh doanh khỉ.
Dưới đây là mô tả về một số mã tôi đã chạy và đầu ra mà nó tạo ra trong nhãn:
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.")
Ok, hãy thử phương thức khởi tạo tiếp theo:
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.")
Tất cả giống như trước đây. Hãy nhớ rằng việc khởi tạo với int? val = new int?(null);
, với null được truyền cho hàm tạo, sẽ tạo ra lỗi thời gian MÁY TÍNH, vì GIÁ TRỊ của đối tượng nullable KHÔNG thể null. Nó chỉ là đối tượng trình bao bọc chính nó có thể bằng null.
Tương tự như vậy, chúng tôi sẽ nhận được một lỗi thời gian biên dịch từ:
int? val = new int?();
val.Value = null;
không đề cập đến dù sao đó val.Value
cũng là một tài sản chỉ đọc, có nghĩa là chúng ta thậm chí không thể sử dụng cái gì đó như:
val.Value = 3;
nhưng một lần nữa, các toán tử chuyển đổi ẩn quá tải đa hình cho phép chúng ta làm:
val = 3;
Không cần phải lo lắng về polysomthing whatchamacallits, miễn là nó hoạt động phải không? :)