2013-07-29 33 views
5

Tôi có các điều kiện sau nếu điều kiện param.days là một chuỗi.Tại sao điều này không được phép trong C#?

if (param.days != null) 

này hoạt động tốt, nhưng nếu tôi nói

If (param.days) 

sau đó nó không đánh giá một cách chính xác khi chạy. Cả hai câu lệnh đều không giống nhau trong C#.
Nó nói rằng giá trị là null nhưng sau đó C# cố gắng để đúc nó vào một bool đó là không nullable. Tại sao các nhà thiết kế C# chọn làm theo cách này? Tuyên bố như vậy hợp lệ trong C++, nhưng tại sao điều này không được coi là hợp lệ trong C#?

+11

null không phải là boolean – Sayse

+4

Loại 'param.days' là gì? –

+0

@Sayse: Có, tôi hiểu điều đó, nhưng có lý do nào khác cho việc này không được đánh giá đúng không. Hay là bởi vì bool là một kiểu không có giá trị và không có cách nào khác. – ckv

Trả lời

18

một tuyên bố như vậy là hợp lệ trong C++, nhưng tại sao điều này không được coi là hợp lệ trong C#

Bởi vì C# giả định quy tắc Languange khác nhau. Nó không giả định rằng mọi số/tham chiếu có thể được coi là một boolean bằng cách kiểm tra nếu nó bằng không so với khác không, null và không null. Nếu bạn muốn kiểm tra xem một cái gì đó có phải là không: kiểm tra xem nó có rỗng không.

Lưu ý: nếu days thực sự là một T? (aka Nullable<T>), sau đó bạn có thể kiểm tra:

if(param.days.HasValue) 

mà sau đó giống với if(param.days != null)

Ngoài ra, nếu loại hình thể hợp lý được điều trị như là một boolean, sau đó có các toán tử bạn có thể ghi đè lên để nói với trình biên dịch đó.

1

Trong C#, câu lệnh If yêu cầu nội dung của các trình kích thước phải là biểu thức logic.

Cân nhắc If ("Hello World").

Có phải "Hello World" đúng hay sai? Nó không phải, nó là một chuỗi.

Bạn có thể muốn xem xét biểu thức LINQ chẳng hạn như .Any() ví dụ: If (myListOfCats.Any()) vì thuộc tính .days của bạn ngụ ý tập hợp các đối tượng.

+2

Đó là một ví dụ khủng khiếp vì 'if (" Hello World ")' sẽ biên dịch trong C++. Câu hỏi hỏi về sự khác biệt giữa C++ và C#, vì vậy điều này không thực sự trả lời. – Dukeling

+3

Nó không phải là 'C++', nó là' C# ' – NibblyPig

+0

@Dukeling Bạn có thể tranh luận câu hỏi thực sự hỏi tại sao C# không hỗ trợ cú pháp có thể trong C++, không nhất thiết là sự khác biệt giữa chúng. –

1

So sánh trong câu lệnh if cần đánh giá thành kết quả boolean. param.days không phải là boolean. Bạn cần so sánh giá trị với giá trị null để nhận kết quả boolean. C# là loại an toàn.

6

C# không giống C++, không ngầm đúc số nguyên thành bool.

1

So sánh trong câu hỏi if yêu cầu kết quả boolean. param.daysstring không phải là boolean. C# không ẩn hoàn toàn integer đến bool.

Bạn cần phải so sánh giá trị null hoặc sử dụng string.IsNullOrEmpty() để có được một kết quả boolean Nếu bạn muốn làm như vậy thử mã này:

if (!string.IsNullOrEmpty(param.days)) 
{ 
} 

HOẶC

if (param.days!=NULL) 
{ 
} 
5

Để làm rõ, điều này là trả lời câu hỏi sửa đổi trong các ý kiến: tại sao các nhà thiết kế C# chọn không thực hiện đánh giá null để boolean trong khi C++ cho phép nó.

Trích từ bài Eric Lippert của "null is not false":

Một số ngôn ngữ cho phép các giá trị null của kiểu giá trị hoặc các loại tài liệu tham khảo, hoặc cả hai, để được điều trị ngầm như Booleans.

Và tương tự cho các loại giá trị có thể vô hiệu; ở một số ngôn ngữ, giá trị null là được xử lý ngầm là "sai".

Các nhà thiết kế của C# coi các tính năng đó và đã từ chối chúng. Đầu tiên, bởi vì xử lý các tham chiếu hoặc các kiểu giá trị không thể sử dụng như Booleans là một thành ngữ khó hiểu và một nguồn lỗi phong phú tiềm ẩn. Và thứ hai, vì ngữ nghĩa nó có vẻ giả thiết để tự động dịch null - có nghĩa là "giá trị này bị thiếu" hoặc "giá trị này là không xác định" - tới "giá trị này là sai về mặt logic".

Câu này cụ thể bao gồm ví dụ string của bạn, nhưng không có loại nào khác có đánh giá ngầm định tiềm ẩn.

Tuy nhiên, người ta có thể phỏng đoán lý do cho các mục như số nguyên không đánh giá thành boolean cũng nằm dưới biểu ngữ là thành ngữ kém hoặc quá tự phụ.

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