La mejor manera de comprobar si bool es nulo en una expresión de condición (si …)


Me preguntaba cuál era la sintaxis más limpia y comprensible para hacer comprobaciones de condición en bolos nullables.

¿ El siguiente estilo de codificación es bueno o malo? ¿Hay alguna manera de expresar la condición mejor / más limpiamente?

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

Especialmente el if (nullableBool ?? false) part. No me gusta el estilo if (x.HasValue && x.Value)...

(no estoy seguro de si la pregunta se ha hecho antes ... no se pudo encontrar algo similar con la búsqueda)

Author: FireSnake, 2010-04-20

12 answers

Creo que muchas personas se concentran en el hecho de que este valor es nullable, y no piensan en lo que realmente quieren:)

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

O si quieres más opciones...

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

(nullableBool == true) nunca volverá verdadero si el bool? es nulo: P

 256
Author: Artiom Chilaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:44:24

Qué tal usar GetValueOrDefault , que es bastante auto-explicativo y permite usar cualquier valor predeterminado que desee:

if (nullableBool.GetValueOrDefault(false)) {
}
 53
Author: Lucero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:36:59

Puede que no te guste, pero personalmente encuentro

if (x.HasValue && x.Value)

El más legible. Deja claro que está trabajando con un tipo nullable y deja claro que primero está comprobando si el tipo nullable tiene un valor antes de actuar sobre él condicionalmente.

Si toma su versión y reemplaza la variable con x también se lee:

if (x ?? false)

¿Está claro? ¿Es obvio que x es un tipo nullable? Dejaré que tú decidas.

 28
Author: Dan Diplo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:34:02

Si quieres tratar un null como falso, entonces diría que la forma más sucinta de hacerlo es usar el operador de coalescencia nulo (??), como describes:

if (nullableBool ?? false) { ... }
 17
Author: Oded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:34:09

Use extensiones.

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
}
 8
Author: Andrey Frolov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-11 07:54:15

Solo piensa en bool? al tener 3 valores, entonces las cosas se vuelven más fáciles:

if (someNullableBool == true)     // only if true
if (someNullableBool == false)    // only if false
if (someNullableBool == null)     // only if null
 5
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-21 09:55:12

Veamos cómo se define la comparación con 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}");
    }

Y los resultados son:

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

Para que pueda usar con seguridad:

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

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

// check if true or false
if (nullable != null) ...
 2
Author: Sz. Moncz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-13 20:12:12

En realidad creo que (nullableBool ?? false) es una opción legítima, especialmente cuando se está tratando de evaluar un bool nullable en linq.

Por ejemplo:
array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

Es más limpio en mi opinión a diferencia de:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)

 2
Author: Zze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-20 01:44:11

Si solo desea probar para true contra null/false, Uno que acabo de usar y lee bastante bien es

bool? someCondition = null
if (someCondition.Equals(true))
...
 1
Author: ds4940,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-14 08:48:03

Creo que depende de ti. Ciertamente creo que el .HasValue enfoque es más legible, especialmente con los desarrolladores no están familiarizados con el ?? sintaxis.

El otro punto de un tipo booleano nullable es que es tristate, por lo que es posible que desee hacer otra cosa cuando es simplemente null, y no false por defecto.

 0
Author: James Westgate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:33:48

Dado enum

public enum PublishMode { Edit, View }

Puedes hacerlo como aquí

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

//or
       if (mode?? PublishMode.Edit == someValue)
       ....
    }
 0
Author: Gopher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-20 09:43:41

Si estás en una situación en la que no tienes control sobre si parte de la condición está comprobando un valor nullable, siempre puedes intentar lo siguiente:

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

Sé que no es exactamente un enfoque purista poner un ternario en una declaración if, pero resuelve el problema limpiamente.

Esto es, por supuesto, una forma manual de decir GetValueOrDefault(false)

 0
Author: MetalPhoenix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-30 16:51:32