2013-05-04 25 views
14

Đây không phải là để giải quyết bất kỳ vấn đề cụ thể nào. Đơn giản chỉ là một câu hỏi về trình biên dịch.Tại sao null == false không dẫn đến lỗi biên dịch trong C#?

Tại sao mã sau không dẫn đến lỗi biên dịch? Nó so sánh một kiểu tham chiếu với kiểu nguyên thủy. Cả hai null và false phải được giải thích vào một cái gì đó cho trình biên dịch để so sánh. Hoặc là trình phân tích cú pháp chỉ đơn giản là quét cho mô hình như vậy và thay thế nó bằng false?

if(null == false) { } 
+4

Loại giá trị hay không, 'false' vẫn là một đối tượng. Nó có thể sẽ được đóng hộp để so sánh. – cHao

+6

@cHao: Giả thuyết của bạn không chính xác. Các nhà điều hành bình đẳng được thiết kế đặc biệt để tránh đấm bốc; đọc thông số kỹ thuật để biết chi tiết. –

Trả lời

28

Đó là hợp pháp vì toán tử so sánh được sử dụng. Nếu bạn so sánh bool với số null, cả hai boolnull được chuyển đổi hoàn toàn thành Nullable<bool> và toán tử so sánh cho Nullable<bool> sẽ được sử dụng. Bạn nhận được một cảnh báo bởi vì rõ ràng, nó luôn luôn là sai.

+4

Tôi thích câu trả lời của bạn tốt hơn, vì nó giải thích _why_ nó được cho phép và _how_ nó hoạt động. Thay vì chỉ nói rõ ràng. Bằng cách này, trình biên dịch (trong chế độ Debug với tối ưu hóa tắt) thậm chí không cố gắng phát ra nó. Nó đơn giản phát ra 'false' vào mã. – Virtlink

+0

Điều này không chính xác, theo phần 7.9.10 của thông số (toán tử bằng nhau và null). Lời giải thích này chỉ áp dụng trong trường hợp, đối với 'null == x',' x' là một kiểu nullable. Thông số trạng thái này tương đương với 'x.HasValue'. Vì 'false' theo nghĩa đen không phải là một kiểu nullable, lý do này là hợp pháp không liên quan đến toán tử so sánh được dỡ bỏ. – drf

+4

'false' có thể không phải là một kiểu nullable, nhưng nó thuộc kiểu' bool' và có một chuyển đổi ngầm giữa 'bool' và' bool? ' –

12

Mục 7.10.6 của đặc tả ngôn ngữ (loại tham khảo các nhà khai thác bình đẳng) khẳng định:

Các x == null xây dựng được phép mặc dù T có thể đại diện cho một loại giá trị, và kết quả chỉ đơn giản được xác định là sai khi T là một loại giá trị.

Quy định này yêu cầu null == falsefalse và không phải lỗi trình biên dịch.

+2

Phần này của thông số chỉ áp dụng cho các thông số loại. –

15

Câu trả lời của Tejas là chính xác. Để cụ thể hơn giải quyết một số điểm của bạn:

Tại sao mã sau không dẫn đến lỗi biên dịch?

Câu hỏi không đáng trả lời; nó không tạo ra một lỗi vì nó là mã pháp lý, nhưng đó là một thuật ngữ.

Nếu câu hỏi của bạn thực sự là "phần nào trong đặc tả C# làm cho điều này hợp pháp?", Thì đó là một câu hỏi có thể trả lời được. Phần trên các nhà khai thác bình đẳng dỡ bỏ làm cho nó hợp pháp.

So sánh loại tham chiếu với loại nguyên thủy.

Nó không phải. Trước hết, tránh thuật ngữ "kiểu nguyên thủy"; các đặc điểm kỹ thuật không xác định rõ ràng nó và nó không phải là một khái niệm hữu ích trong C#. Bạn có nghĩa là để nói rằng tôi nghĩ rằng nó là so sánh một giá trị của loại tài liệu tham khảo để một giá trị của loại giá trị.

Thứ hai, điều đó cũng không đúng. Chữ rỗng không phải kiểu tham chiếu hoặc kiểu giá trị; nó không thuộc loại nào cả. Đó là có thể chuyển đổi thành bất kỳ loại giá trị có thể vô giá nào hoặc bất kỳ loại tham chiếu nào, nhưng không phải chỉ loại nào.

Trong trường hợp này, chữ rỗng được chuyển thành loại bool có thể vô hiệu hóa.

Cả hai giá trị rỗng và sai phải được hiểu là điều gì đó để trình biên dịch so sánh.

Đúng. Chúng được hiểu là bool nullable.

là trình phân tích cú pháp chỉ cần quét mẫu đó và thay thế bằng sai?

Không, nhưng đó là một dự đoán tuyệt vời. Trình biên dịch sẽ không đổi lần, giả sử, true == false xuống đến false, nhưng nó không thực hiện tối ưu hóa gấp có liên quan đến các loại giá trị không thể thực hiện được. Ngôn ngữ có thể được thiết kế lại để hỗ trợ việc gấp liên tục trên các phép toán với các toán hạng kiểu giá trị rỗng; đã có các kiểu giá trị vô hiệu hóa được phản đối trong phiên bản một, tính năng được đề xuất có thể sẽ được hỗ trợ.

+0

Cảm ơn bạn đã thiết lập hồ sơ thẳng. – weilin8

+0

So sánh cũng có hợp lệ trong C# trước các kiểu nullable không? –

+0

@AndersForsgren: Được * so sánh * gì hợp lệ, trong đó phiên bản của C#? –

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