Cách tốt nhất để kiểm tra bool nullable trong biểu thức điều kiện (nếu Bằng)


207

Tôi đã tự hỏi đâu là cú pháp rõ ràng và dễ hiểu nhất để thực hiện kiểm tra điều kiện trên các bool nullable.

Là phong cách mã hóa tốt hay xấu sau đây? Có cách nào để thể hiện tình trạng tốt hơn / sạch hơn không?

bool? nullableBool = true;
if (nullableBool ?? false) { ... }
else { ... }

đặc biệt là phần if (nullableBool ?? false) . Tôi không thích if (x.HasValue && x.Value)phong cách ...

(không chắc câu hỏi đã được hỏi trước đó chưa ... không thể tìm thấy câu hỏi tương tự với tìm kiếm)

Câu trả lời:


361

Tôi nghĩ rằng rất nhiều người tập trung vào thực tế là giá trị này là vô giá trị và đừng nghĩ về những gì họ thực sự muốn :)

bool? nullableBool = true;
if (nullableBool == true) { ... } // true
else { ... } // false or null

Hoặc nếu bạn muốn có thêm tùy chọn ...

bool? nullableBool = true;
if (nullableBool == true) { ... } // true
else if (nullableBool == false) { ... } // false
else { ... } // null

(nullableBool == true)Sẽ không bao giờ trở lại đúng nếu bool? là null: P


2
Tôi đã không nhận ra rằng so sánh vô giá trị có ý nghĩa như thế này. Thông tin chi tiết có thể được tìm thấy tại msdn.microsoft.com/en-us/l
Library / 2cf62fcy.aspx

79

Còn về cách sử dụng GetValueOrDefault , điều này khá tự giải thích và cho phép sử dụng bất kỳ mặc định nào bạn muốn:

if (nullableBool.GetValueOrDefault(false)) {
}

6
Tùy thuộc vào bối cảnh phương pháp này có thể némSystem.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean GetValueOrDefault()' method, and this method cannot be translated into a store expression.
Nano Taboada

3
Tôi thích cách tiếp cận này vì nó cũng hoạt động trong một câu lệnh non-if (tức là gán).
paultechguy 17/03/18

48

Bạn có thể không thích nó, nhưng cá nhân tôi tìm thấy

if (x.HasValue && x.Value)

dễ đọc nhất Nó cho thấy rõ bạn đang làm việc với một loại nullable và nó cho thấy rõ rằng trước tiên bạn đang kiểm tra xem loại nullable có giá trị hay không trước khi hành động một cách có điều kiện.

Nếu bạn lấy phiên bản của mình và thay thế biến bằng x thì nó cũng sẽ đọc:

if (x ?? false)

Điều đó có rõ ràng không? Rõ ràng x là một loại nullable? Tôi sẽ để bạn quyết định.


afaik, ?? chỉ hoạt động trên các loại nullable. Cộng với biến nên có tên đẹp hơn x :)
FireSnake

5
Theo "loại nullable", tôi có nghĩa là các loại System.Nullable cụ thể. Bất kỳ loại tham chiếu có thể là null. Ngoài ra, nếu bạn cần sử dụng loại biến như một phần của tên của nó thì đó là dấu hiệu cho thấy mã của bạn không rõ ràng.
Dan Diplo

@DanDiplo Làm thế nào để viết UT cho việc này?
Prashant Yadav

xlà tốt trong bối cảnh và đôi khi sạch hơn; dí dỏm:var openOrders = orders.Where(x=>x.Open ?? false)
gì cần thiết vào

21

Nếu bạn muốn coi một nullsai là sai, thì tôi sẽ nói rằng cách ngắn gọn nhất để làm điều đó là sử dụng toán tử coalesce null ( ??), như bạn mô tả:

if (nullableBool ?? false) { ... }

8

Chỉ cần nghĩ về bool? có 3 giá trị, mọi thứ trở nên dễ dàng hơn:

if (someNullableBool == true)     // only if true
if (someNullableBool == false)    // only if false
if (someNullableBool == null)     // only if null

8

Sử dụng phần mở rộng.

public static class NullableMixin {
    public static bool IsTrue(this System.Nullable<bool> val) {
        return val == true;
    }
    public static bool IsFalse(this System.Nullable<bool> val) {
        return val == false;
    }
    public static bool IsNull(this System.Nullable<bool> val) {
        return val == null;
    }
    public static bool IsNotNull(this System.Nullable<bool> val) {
        return val.HasValue;
    }
}


Nullable<bool> value = null;
if(value.IsTrue()) {
// do something with it
}

Điều gì nếu bạn muốn xem xét nullnhư true?
Thibault Falise

IsTrue () | IsNull () .. :) Tôi đã tái tạo logic cách SQL hoạt động với null. Tôi nghĩ rằng đó là cú pháp rõ ràng và dễ hiểu nhất.
Andrey Frolov

Nó phải là công cụ tĩnh bool IsFalse (Hệ thống này. Giá trị val) {return! Val ?? thật; } coi null là sai
Michael Freidgeim

2
Nó có thể thiếu dấu chấm phẩy (;) trong hai phương thức cuối (ví dụ IsNull và IsNotNull)
garson

4

Hãy kiểm tra cách so sánh với null được xác định:

static void Main()
    {
        Console.WriteLine($"null != null  => {null != null}");
        Console.WriteLine($"null == null  => {null == null}");
        Console.WriteLine($"null != true  => {null != true}");
        Console.WriteLine($"null == true  => {null == true}");
        Console.WriteLine($"null != false => {null != false}");
        Console.WriteLine($"null == false => {null == false}");
    }

và kết quả là:

null != null  => False                                                                                                                                                                                                                                  
null == null  => True                                                                                                                                                                                                                                   
null != true  => True                                                                                                                                                                                                                                   
null == true  => False                                                                                                                                                                                                                                  
null != false => True                                                                                                                                                                                                                                   
null == false => False

Vì vậy, bạn có thể sử dụng một cách an toàn:

// check if null or false
if (nullable != true) ...

// check if null or true
if (nullable != false) ...

// check if true or false
if (nullable != null) ...

Tôi chỉ tự hỏi tại sao chúng ta không thể làm nếu (không thể) .... điều đó sẽ được xử lý nhưng cần được xử lý một cách thận trọngif(nullable)...else if(!nulllable)...else..
IronHide

Tôi sẽ nói rằng trong những năm qua, phong cách mã hóa (do có sẵn các công cụ như stylecop, máy phân tích, v.v.) ngày càng thích mã rõ ràng, rõ ràng, "xác nhận ý định" (ví dụ: khuyến nghị sử dụng dấu ngoặc đơn không cần thiết chỉ để xác nhận mục đích sử dụng ưu tiên nhà khai thác, hoặc sử dụng các hệ thống chú thích / hợp đồng khác nhau). IMO giới thiệu một cú pháp như vậy sẽ gây ra nhiều nhầm lẫn hơn do mức độ không rõ ràng về cách xử lý nullables so với lợi ích.
Sz. Moncz

4

Trên thực tế tôi nghĩ rằng đó (nullableBool ?? false)là một lựa chọn hợp pháp đặc biệt là khi bạn đang cố gắng đánh giá một bool nullable trong linq.

Ví dụ:
array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

Theo tôi thì sạch hơn là trái ngược với:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)


1

Nếu bạn chỉ muốn kiểm tra truechống lại null/ false, thì tôi đã sử dụng và đọc khá tốt là

bool? someCondition = null
if (someCondition.Equals(true))
...

1
Bạn không nhận được một ngoại lệ tham chiếu null ở đây?
Chase Florell

@ChaseFlorell Tôi đã phải kiểm tra kỹ điều này trong cửa sổ VS Interactive .. Vì vậy, điều cần nhớ là loại somecondition là Nullable <bool>. Bạn vẫn có thể gọi các phương thức được kế thừa từ đối tượng (như Equals), HasValue và GetValueOrDefault , nhưng không phải là Giá trị
DS4940

Thật thú vị, tôi có thể thấy điều đó ngay bây giờ. Vẫn còn sơ sài cho các loại tham chiếu dotnetfiddle.net/8cAI21
Chase Florell

0

Tôi nghĩ rằng nó tùy thuộc vào bạn. Tôi chắc chắn nghĩ rằng cách tiếp cận .HasValue dễ đọc hơn, đặc biệt là với các nhà phát triển không quen thuộc với ?? cú pháp.

Điểm khác của kiểu boolean nullable là nó là tristate, vì vậy bạn có thể muốn làm một cái gì đó khác khi nó chỉ là null và không được mặc định là false.


0

Cho enum

public enum PublishMode { Edit, View }

bạn có thể làm nó như ở đây

 void MyMethod(PublishMode? mode)
    {
       var publishMode = mode ?? PublishMode.Edit;

//or
       if (mode?? PublishMode.Edit == someValue)
       ....
    }

Không phải là một câu trả lời cho câu hỏi, mà cụ thể là về nullable boolean.
ToolmakerSteve

0

Nếu bạn đang ở trong tình huống mà bạn không kiểm soát được liệu một phần của điều kiện có kiểm tra giá trị không thể thực hiện được hay không, bạn luôn có thể thử các cách sau:

if( someInt == 6 && someNullableBool == null ? false : (bool)someNullableBool){
    //perform your actions if true
}

Tôi biết đó không chính xác là một cách tiếp cận theo chủ nghĩa thuần túy đưa một câu nói ngắn gọn vào câu lệnh if nhưng nó giải quyết vấn đề một cách sạch sẽ.

Tất nhiên, đây là một cách nói thủ công GetValueOrDefault(false)


3
Giải pháp được cung cấp trong OP là điều tương tự, nhưng chỉ với sự phình to mã ít hơn nhiều. Điều này không có lợi cho điều đó.
Phục vụ
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.