Giá trị mặc định của kiểu nullable “int?” (kể cả dấu chấm hỏi)?


100

Trong C #, giá trị mặc định của một biến thể hiện lớp có kiểu là int?gì?

Ví dụ, trong đoạn mã sau, giá trị nào sẽ MyNullableIntcó nếu nó không bao giờ được gán rõ ràng?

class MyClass
{
    public int? MyNullableInt;
}

(Có vẻ như câu trả lời gần như chắc chắn là nullhoặc hoặc 0, nhưng đó là câu trả lời nào?)


9
Tại sao lại ủng hộ? (Câu trả lời cho câu hỏi này ban đầu không rõ ràng đối với tôi nếu không thực sự chạy mã để kiểm tra hành vi; và thật ngạc nhiên, tôi không thể tìm thấy bản sao của câu hỏi này trên StackOverflow hoặc có thể dễ dàng tìm thấy ở nơi khác thông qua Google.)
Jon Schneider

1
Bạn có thể đã xem ở đây - lần đầu tiên google truy cập cho tôi.
500 - Lỗi máy chủ nội bộ vào

2
@ 500 - Tôi đã tìm thấy bài báo đó khi tôi đang nghiên cứu - tôi thực sự đã liên kết với nó trong câu trả lời của riêng tôi bên dưới - nhưng theo như tôi có thể nói, bài viết không nêu rõ ràng rằng giá trị mặc định của một trường hợp kiểu nullable là null. Nó không nói "Giá trị mặc định cho HasValue là sai. Khu nghỉ dưỡng Giá trị không có giá trị mặc định", nhưng điều đó không trực tiếp trả lời câu hỏi ban đầu của tôi mà không cần đào một số bổ sung.
Jon Schneider

2
Tôi tự hỏi có phải vì bạn chỉ có thể đặt một điểm ngắt và xem giá trị là gì, hay trong loại Cửa sổ ngay lập tức int? x;và xem kết quả là gì?
Rufus L

Câu trả lời:


135

Giá trị mặc định cho int?- và cho bất kỳ kiểu nullable nào sử dụng "loại?" khai báo - là null.

Tại sao lại như vậy:

  • int?là đường cú pháp cho kiểu Nullable <T> (trong đó T là int), một cấu trúc. ( tham khảo )
  • Các Nullable<T>loại có một HasValue bool thành viên, mà khi false, làm cho Nullable<T>dụ "hành động như" một nullgiá trị. Đặc biệt, Nullable <T> Phương pháp Equals được ghi đè để trở lại truekhi một Nullable<T>với HasValue == falseđược so sánh với một thực tế nullgiá trị.
  • Từ Đặc tả ngôn ngữ C # 11.3.4 , giá trị mặc định ban đầu của thể hiện struct là tất cả các trường kiểu giá trị của struct đó được đặt thành giá trị mặc định của chúng và tất cả các trường kiểu tham chiếu của struct đó được đặt thành null.
  • Giá trị mặc định của một boolbiến trong C # là false ( tham chiếu ). Do đó, thuộc HasValuetính của một Nullable<T>instance mặc định là false; do đó làm cho Nullable<T>cá thể đó hoạt động như thế nào null.

Khi tôi thay đổi một khai báo từ int? x = null;thành int? x;, tôi nhận được thêm lỗi trình biên dịch trong mã: "Sử dụng biến cục bộ chưa được gán x".
John Pick

1
@JohnPick Đó là một tính năng của trình biên dịch C # nhằm ngăn chặn các lỗi có thể phát sinh do bạn "quên" khởi tạo một biến trước khi sử dụng nó. Một tình huống mà bạn có thể gặp phải một int chưa được khởi tạo? là khi nó là một biến thành viên của lớp. Ví dụ về cả hai tại đây: blogs.msdn.microsoft.com/abhinaba/2005/11/08/…
Jon Schneider

Vì vậy, về cơ bản nơi này là blog công nghệ của bạn? Bạn đặt câu hỏi mà bạn chỉ cần chạy mã để nhận câu trả lời, sau đó tự trả lời câu hỏi trong cùng một phút.
GôTô 17/11/16

4
@JonSchneider đủ công bằng rồi, tệ thật đấy
GôTô 17/11/16

VS của trình biên dịch gợi ý / cảnh báo được gây hiểu lầm: Field 'id' is never assigned to, and will always have its default value 0. Kỳ lạ phải không?
Hendy Irawan

30

Tôi cảm thấy quan trọng khi chia sẻ Nullable<T>.GetValueOrDefault()phương pháp đặc biệt hữu ích khi làm việc với các phép tính toán sử dụng giá trị Nullable<int>aka int?. Có nhiều khi bạn không phải kiểm tra HasValuetài sản và bạn có thể sử dụng GetValueOrDefault()thay thế.

var defaultValueOfNullableInt = default(int?);
Console.WriteLine("defaultValueOfNullableInt == {0}", (defaultValueOfNullableInt == null) ? "null" : defaultValueOfNullableInt.ToString());

var defaultValueOfInt = default(int);
Console.WriteLine("defaultValueOfInt == {0}", defaultValueOfInt);

Console.WriteLine("defaultValueOfNullableInt.GetValueOrDefault == {0}", defaultValueOfNullableInt.GetValueOrDefault());

Dòng lệnh hiển thị mã ở trên đang hoạt động


0
var x = default (int?);
Console.WriteLine("x == {0}", (x == null) ? "null" : x.ToString());
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.