2008-12-29 28 views
5

Tôi đã có một cuộc trò chuyện với một đồng nghiệp và chủ đề của null đã đưa ra. Anh ấy nói với tôi rằng .NET đằng sau hậu trường nó chỉ là một con số thực sự nhỏ. Tôi luôn nghĩ rằng vật thể đó không có con trỏ tới bất kỳ bộ nhớ nào trên heap nhưng tôi không chắc chắn một trong hai cách.Làm thế nào là null đại diện trong NET

Vì vậy, tôi hy vọng cộng đồng có thể xóa nó lên cho chúng ta; P

Trả lời

5

Khi một thể loại kiểu nullable được đặt thành null, giá trị cơ bản của nó bằng 0.

Để cụ thể hơn, một loại nullable là một cấu trúc kết hợp giá trị của loại cơ bản cùng với một chỉ báo null boolean. Một thể hiện của một loại nullable có hai thuộc tính chỉ đọc công khai: HasValue kiểu bool và Giá trị loại cơ bản của loại có thể loại bỏ.

HasValue là đúng đối với trường hợp không trống và sai cho một phiên bản trống.

Vì vậy, khi HasValue là đúng, giá trị Giá trị trả về giá trị chứa. Khi HasValue là sai, cố gắng truy cập thuộc tính Giá trị sẽ ném ngoại lệ. Nhưng nếu bạn có thể truy cập nó, bạn sẽ thấy nó có số không.

+0

Awesome này là chính xác những gì tôi đang tìm kiếm. – Alex

+0

Đây là tất cả về 'Nullable ' - đó là * không * về tham chiếu null. –

+0

@Jon, bạn đang nói rằng việc tôi sử dụng từ "cá thể" là không chính xác? – RoadWarrior

0

từ kinh nghiệm của tôi, tôi tin rằng Nothing sẽ làm việc, và như vậy sẽ DBNull.Value

+0

... Và tôi hoàn toàn hiểu nhầm nó. Tôi tin Null hoặc 'Nothing' tương đương với số không, và được lưu trữ như bất kỳ kiểu dữ liệu nào mà biến được gán cho nó – Sukasa

+0

Có lẽ tốt nhất là xóa câu trả lời, nếu không bạn sẽ nhận được phiếu bầu :) +1 cho sự trung thực – leppie

+0

Và bây giờ bạn thấy sự khác biệt giữa == và ===, hãy thử so sánh các loại null khác nhau này. – TravisO

15

Đó là 0.

Snip từ ldnull trong thông số ECMA-335:

Có thể nghĩ rằng ldnull là dự phòng: tại sao không sử dụng ldc.i4.0 hoặc ldc.i8.0 thay thế? Câu trả lời là ldnull cung cấp một null kích thước bất khả tri - tương tự như lệnh ldc.i, không tồn tại. Tuy nhiên, ngay cả khi CIL phải bao gồm hướng dẫn về ldc.i , nó vẫn sẽ mang lại lợi ích cho các thuật toán xác minh để giữ lại hướng dẫn gọn gàng vì nó giúp việc theo dõi loại dễ dàng hơn.

+0

Tôi thực sự phải không đồng ý rằng null là 0 ... 0 là một giá trị ... null là một giữ chỗ cho sự vắng mặt của một tham chiếu đến một đối tượng. Để khởi tạo một đối tượng là null và sau đó nói "oh, nó cũng bằng giá trị 0" là một chút mâu thuẫn trong quan điểm của tôi – lomaxx

+1

@ lomaxx - nó thực sự là số không; đó là cách nó được triển khai ở cấp CIL. Bạn có thể nghĩ về nó như là một địa chỉ bộ nhớ đặc biệt được hiểu là null. –

+1

@lomaxx: null chắc chắn là một giá trị. Bạn có thể làm tất cả mọi thứ với nó mà bạn có thể với một giá trị khác - vượt qua nó, gán nó vào một biến vv. * Biểu diễn bitwise * của nó là tất cả các số không. –

-2

Từ MSDN:

Từ khóa null là một chữ mà đại diện cho một tham chiếu null, một trong những không đề cập đến bất kỳ đối tượng

Để thử và làm cho nó một chút rõ ràng hơn trong các phiên bản cũ hơn của C#, một loại giá trị không thể là rỗng, nghĩa là, nó HAD có giá trị, nếu bạn không gán giá trị, bạn có một giá trị ngẫu nhiên tiềm ẩn, chẳng hạn như:

int i; 
i++; 
console.writeline(i); 

trong các phiên bản cũ hơn của các đối tượng C# phải được khởi tạo nếu không chúng không có nghĩa là chúng không có tham chiếu đến bất kỳ đối tượng nào.

Bây giờ với các loại giá trị nullable trong C# 2.0+ bạn có thể có một int nullable điều đó có nghĩa rằng nếu bạn có mã này:

int? i; 
i++; 
console.writeline(i); 

bạn sẽ thực sự có được một ngoại lệ tại i ++, vì tôi chưa bao giờ được khởi tạo bất cứ điều gì khác hơn là null. Nếu null là 0, mã này sẽ thực thi tốt vì nó chỉ đánh giá là 0 + 1, tuy nhiên đây là hành vi không chính xác.

Nếu null luôn 0 và bạn có aa int nullable, và bạn đã viết một số mã như:

int? i; 
if (int == 0) 
{ 
//do something 
} 

có một khả năng rất thực tế bạn có thể nhận được một số hành vi bất ngờ NẾU rỗng là giống như 0 vì không có cách nào trình biên dịch có thể phân biệt giữa int là null và int được đặt rõ ràng là 0.

Một ví dụ khác là làm rõ mọi thứ trong tâm trí tôi:

public int? AddNumbers(int? x, int? y) 
{ 
    if (x == null || y == null) 
     return null; 
    if (x == 0) 
     return y; 
    if (y == 0) 
     return x; 

    return x + y; 
} 

trong ví dụ này, thì rõ ràng rằng vô 0 là rất khác nhau, vì nếu bạn đã vượt qua trong 0 cho x hoặc y, và null là bình đẳng 0, sau đó mã ở trên sẽ không bao giờ nhận được để kiểm tra cho x == 0 hoặc y == 0, tuy nhiên nếu bạn chạy mã và vượt qua trong 0 cho x hoặc y, kiểm tra được thực thi.

+0

Tôi không nghĩ rằng điều này sẽ giúp ích. Hành vi của các toán tử được dỡ bỏ có ít liên quan đến giá trị cơ bản của null. Và khi nó xảy ra, giá trị nhị phân của một "null" Nullable * là * không. Tất cả số không. Vì vậy, cho int? nó là 5 số không (một cho cờ bool, 4 cho int). –

+0

(lưu ý, -1 không phải là từ tôi; tôi muốn trả lại qua nhận xét - không chỉ bỏ phiếu một cách mù quáng) –

+0

nhưng nếu giá trị null * là * không, thì giá trị bằng 0 là bao nhiêu? làm thế nào để bạn phân biệt giữa hai? – lomaxx

Các vấn đề liên quan