2008-12-17 28 views
6

Tôi hiểu rằng boxing và unboxing là về việc đúc (loại thực đối tượng ... đối tượng thành loại thực). Nhưng tôi không hiểu những gì MSDN nói về nó với Nullable. Đây là văn bản tôi không hiểu:Boxing/Unboxing và Nullable?

Khi một loại có thể có giá trị rỗng được đóng hộp, thời gian chạy ngôn ngữ chung tự động đóng hộp giá trị cơ bản của đối tượng không thể bỏ qua, không phải chính đối tượng không thể bỏ qua. Nghĩa là, nếu thuộc tính HasValue là true, nội dung của thuộc tính Value được đóng hộp. Khi giá trị cơ bản của một kiểu nullable là unboxed, thời gian chạy ngôn ngữ chung tạo ra một cấu trúc Nullable mới được khởi tạo cho giá trị cơ bản. Source

Khi bạn thay đổi đối tượng thành loại thực, biến loại thực có thể vô hiệu hóa sẽ là loại đối tượng? Tôi không hiểu?

+0

Tâm trí tuyệt vời nghĩ như nhau. (cf @Jon và @Marc) – harpo

+2

Tâm trí tuyệt vời cần phải có một kỳ nghỉ từ SO :) – mackenir

Trả lời

10

gì nó nói là nếu bạn làm:

int? x = 5; 
object y = x; // Boxing 

Bạn kết thúc với một đóng hộp int, không phải là một đóng hộp Nullable<int>. Tương tự, nếu bạn làm như vậy:

int? x = null; // Same as new Nullable<int>() - HasValue = false; 
object y = x; // Boxing 

Sau đó, y kết thúc bằng tham chiếu null.

+4

lol! thuần túy trùng hợp ngẫu nhiên, nhưng đáng sợ không có-the-ít hơn –

+0

@ Jon trong trường hợp thứ hai, không có quyền anh, tài liệu rõ ràng về nó. Nó chỉ gán một tham chiếu null. Chỉ khi cờ 'HasValue' là đúng (giá trị không null), kiểu giá trị cơ sở được đóng hộp.Spot on about * Bạn kết thúc với một 'int' đóng hộp, không phải là một đóng hộp' Nullable '*, tôi đã có quan niệm sai lầm bản thân mình. – nawfal

+0

@nawfal: Nó gán một tham chiếu null, nhưng đó là một hoạt động đấm bốc mà mang lại một tham chiếu null. Nhìn vào IL tạo ra (tôi chỉ cần kiểm tra gấp đôi) - nó sử dụng lệnh 'box'. Có sự khác biệt giữa "hoạt động quyền anh" và "một hoạt động trả về giá trị đóng hộp" IMO. Bạn đang đề cập đến tài liệu nào? –

8

Điều đó có nghĩa là nếu bạn làm:

int? i = 5; 
object o = i; 

nó là một "int" (5) được đóng hộp, không phải là một "int?" (5). Nếu x đã được null (! HasValue), o sẽ là null, không phải là một hộp xung quanh một rỗng "int?"

Sau đó, khi bạn Unbox:

i = (int?)o; 

Nếu o là null, tôi sẽ trở thành một sản phẩm nào; "int?" nếu không, số 5 không được đóng hộp và được sử dụng để tạo "int mới? (5)".

Về cơ bản, bạn không nên (viết tắt của gian lận) có thể nhận được một đóng hộp nullable<T> trực tiếp - chỉ là một đóng hộp T

+1

Vì vậy, làm thế nào đến cả hai chúng tôi đã chọn 5 làm giá trị ví dụ của chúng tôi? Hmm ... –

+0

Sao nó không phải là 42? –

+0

"Nếu x đã được null" nên là "Nếu tôi đã được null" ... x biến là trên ví dụ JonSkeet ... bạn đã sử dụng i. –

3

Nếu một Nullable<T>null, nó sẽ được đóng hộp như một tham chiếu null và sẽ không hoạt động như một loại giá trị được đóng hộp với HasValue = true.

Thực tế, để triển khai tính năng này, CLR thực sự cần hỗ trợ loại hình Nullable<T> và xử lý nó theo cách khác. Nhà phát triển không thể viết loại riêng của họ hoạt động như Nullable<T>.

Cần lưu ý rằng đây là một trong các tính năng .NET 2.0 muộn. Trong các bản beta đầu tiên, Nullable<T> hoạt động giống như cấu trúc bình thường. Trong bản phát hành cuối cùng, nó đã được thay đổi thành hộp để tham chiếu null. Thay đổi này đã được cụ thể phá vỡ cho đội ngũ SQL Server CLR và họ đã phải thay đổi một số công cụ cơ bản cho nó.