Найкращий спосіб перевірити нульовий bool у виразі стану (якщо…)


207

Мені було цікаво, що є найбільш чистим і зрозумілим синтаксисом для перевірки стану на нульові bools.

Чи є наступний хороший чи поганий стиль кодування? Чи є спосіб виразити стан краще / більш чисто?

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

особливо, якщо if (nullableBool ?? false) частина. Мені не подобається if (x.HasValue && x.Value)стиль ...

(не впевнений, чи було раніше задане питання ... не вдалося знайти щось подібне при пошуку)

Відповіді:


361

Я думаю, що багато людей концентруються на тому, що ця величина є нульовою, і не думають про те, чого вони насправді хочуть :)

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

Або якщо ви хочете більше варіантів ...

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

(nullableBool == true)ніколи не повернеться правдою, якщо бул? є нульовим: P


2
Я не усвідомлював, що таке нульове порівняння має значення, як це. Деталі можна знайти на сайті msdn.microsoft.com/en-us/library/2cf62fcy.aspx
Micah Zoltu

79

Як щодо використання GetValueOrDefault , який досить самоосмислюється і дозволяє використовувати все, що ви хочете за замовчуванням:

if (nullableBool.GetValueOrDefault(false)) {
}

6
Залежно від контексту, який цей підхід може кинутиSystem.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean GetValueOrDefault()' method, and this method cannot be translated into a store expression.
Нано Табоада

3
Мені подобається такий підхід, оскільки він також працює в операторі non-if (тобто присвоєнні).
paultechguy

48

Вам це може не сподобатися, але особисто я знаходжу

if (x.HasValue && x.Value)

найбільш читабельний. Це дає зрозуміти, що ви працюєте з зведеним типом, і це дає зрозуміти, що ви спочатку перевіряєте, чи має тип nullable значення, перш ніж діяти на нього умовно.

Якщо ви берете свою версію і замінюєте змінну на x, вона також говорить:

if (x ?? false)

Це так зрозуміло? Чи очевидно, що x є нульовим типом? Я дам вам вирішити.


afaik, ?? працює лише на змінних типах. Плюс змінна повинна мати приємнішу назву, ніж x :)
FireSnake

5
Під "нульовим типом" я мав на увазі конкретно системи System.Nullable. Будь-який тип посилання може бути недійсним. Крім того, якщо вам потрібно використовувати тип змінної як частину її імені, то це показово, ваш код не зрозумілий.
Дан Дипл

@DanDiplo Як написати UT для цього?
Прашант Ядав

xдобре в контексті і іноді є більш чистим; а саме:var openOrders = orders.Where(x=>x.Open ?? false)
nothingisnecessary

21

Якщо ви хочете трактувати nullяк помилкове, я б сказав, що найкоротший спосіб зробити це - використовувати оператор null coalesce ( ??), як ви описуєте:

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

8

Подумайте лише про bool? як 3 значення, то все стає простіше:

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

8

Використовуйте розширення.

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
}

Що робити, якщо ви хочете вважати nullце true?
Тібо Фоліз

IsTrue () | IsNull () .. :) Я відтворив логіку, як SQL працює з нулями. Я думаю, що це найбільш чистий і зрозумілий синтаксис.
Андрій Фролов

Це повинен бути загальнодоступний статичний bool IsFalse (ця System.Nullable val) {return! Val ?? правда; } вважати недійсним помилковим
Майкл Фрейджім

2
Можливо, у двох останніх методах (тобто IsNull та IsNotNull) відсутні крапки з комою (;)
glenn garson

4

Давайте перевіримо, як визначено порівняння з null:

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}");
    }

і результати:

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

Тож можна сміливо використовувати:

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

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

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

Мені просто цікаво, чому ми не можемо зробити, якщо (незмінна) .... це було б if(nullable)...else if(!nulllable)...else..
справою,

Я б сказав, що протягом останніх років стиль кодування (через доступність таких інструментів, як stylecop, аналізатори тощо) все більше віддає перевагу однозначному, зрозумілому коду "підтвердження намірів" (наприклад, рекомендувати використовувати непотрібні дужки просто для підтвердження наміченого використання пріоритет операторів або використання різних систем анотацій / контрактів). Введення IMO такого синтаксису спричинило б набагато більше плутанини через рівень неясності, яким обробляються конфігурації, ніж користь.
Sz. Moncz

4

Насправді я вважаю, що (nullableBool ?? false)це законний варіант, особливо коли ви намагаєтеся оцінити нульовий bool у linq.

Наприклад:
array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

На мою думку, чистіше, на відміну від:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)


1

Якщо ви хочете тільки тест для trueAGAINST null/ false, Один я просто використав і читає дуже добре це

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

1
Ви тут не отримуєте нульового посилання?
Чейз Флорелл

@ChaseFlorell Мені довелося двічі перевірити це в інтерактивному вікні VS .. Тож слід пам’ятати, що тип деякої умови є Nullable <bool>. Ви все ще можете викликати методи, успадковані від об'єкта (наприклад, рівний), HasValue і GetValueOrDefault , але не цінність
ds4940

Цікаво, я зараз це бачу. Як і раніше схематично для довідкових типів dotnetfiddle.net/8cAI21
Чейз Флорелл,

0

Я думаю, це залежить від вас. Я звичайно думаю, що .HasValue підхід є більш читабельним, особливо з розробниками, не знайомими ?? синтаксис.

Іншим моментом нульового булевого типу є те, що він є тристатом, тому ви, можливо, захочете зробити щось інше, коли це просто нуль, а не за замовчуванням - false.


0

З огляду на перерахунок

public enum PublishMode { Edit, View }

ви можете зробити це як тут

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

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

Не відповідь на запитання, про яке конкретно йдеться nullable boolean.
ToolmakerSteve

0

Якщо у вас є ситуація, коли ви не маєте контролю над тим, чи є частина умови перевірки нульового значення, ви завжди можете спробувати наступне:

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

Я знаю, що це не зовсім пуристський підхід, який ставить потрійника в заяві if, але він вирішує проблему чисто.

Це, звичайно, ручний спосіб висловлювання GetValueOrDefault(false)


3
Рішення, що надається в ОП, - це те саме, але лише з набагато меншим кодом. Це зовсім не вигідно цьому.
Сервіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.