2010-04-20 15 views
105

Me preguntaba cuál era la sintaxis más limpia y comprensible para hacer verificaciones de condiciones en bools nullable.La mejor manera de comprobar bool nullable en una expresión de condición (si ...)

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

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

especialmente la si (nullableBool ?? false) parte. No me gusta el estilo if (x.HasValue && x.Value) ...

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

Respuesta

216

Creo que una gran cantidad de personas se concentran en el hecho de que este valor es anulable, y no pensar 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

+11

¡Observación increíblemente increíble! – seebiscuit

+0

No me di cuenta de que la comparación nullable era significativa como esta. Los detalles se pueden encontrar en https://msdn.microsoft.com/en-us/library/2cf62fcy.aspx –

0

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

El otro punto de un tipo booleano que admite nulos es que es de estado triple, por lo que es posible que desee hacer otra cosa cuando solo sea nulo, y no predeterminado a falso.

25

Es posible que no le guste, pero personalmente me parece

if (x.HasValue && x.Value) 

la más legible. Deja en claro que está trabajando con un tipo de nullable y deja en claro que primero está comprobando si el tipo que admite nulos tiene un valor antes de actuar de forma condicional.

Si usted toma su versión y reemplazar la variable x se lee también:

if (x ?? false) 

es que tan clara? ¿Es obvio que x es un tipo anulable? Te dejaré decidir.

+0

que yo sepa,? ? solo funciona en tipos anulables. Más la variable debe tener un nombre más bonito que x :) – FireSnake

+4

Por "tipo anulable" me refería a los tipos específicamente System.Nullable. Cualquier tipo de referencia puede ser nulo. Además, si necesita usar el tipo de una variable como parte de su nombre, entonces eso es indicativo de que su código no está claro. –

+4

Esta respuesta es mucho mejor y más práctico que la respuesta aceptada ... –

16

Si desea tratar una null como falso, entonces yo diría que la forma más sucinta de hacerlo es utilizar el operador nula coalescencia (??), como usted la describe:

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

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 
} 
+0

Su método 'extensión IsNotNull' es incorrecta. – Oded

+0

¿Qué sucede si quieres considerar 'null' como' verdadero'? –

+0

IsTrue() | IsNull() .. :) Reproduje la lógica de cómo SQL funciona con nulos. Creo que es la sintaxis más clara y comprensible. –

44

Cómo sobre el uso GetValueOrDefault, que es bastante autoexplicativo y permite utilizar cualquier defecto que desee:

if (nullableBool.GetValueOrDefault(false)) { 
} 
+2

Según el contexto, este enfoque podría arrojar 'System.NotSupportedException: LINQ to Entities no reconoce el método método 'booleana GetValueOrDefault()', y este método no se pueden traducir en una tienda expression.' –

+1

gracias. Estoy utilizando solo GetValueOrDefault() ya que está predeterminado en falso. –

0

enumeración Dada

public enum PublishMode { Edit, View } 

puede hacerlo como aquí

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

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

No es una respuesta a la pregunta, que es específicamente sobre 'boolean' anulable. – ToolmakerSteve

-1

Si estás en una situación en la que no tiene control sobre si parte de la condición está comprobando un valor anulable, siempre se puede intentar lo siguiente:

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

que sé no es exactamente un enfoque purista poner un ternario en una declaración if, pero sí resuelve el problema de manera clara.

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

+1

La solución proporcionada en el PO es lo mismo, pero sólo con mucho menos hinchazón de código. Esto no es en absoluto ventajoso para eso. – Servy

2

Permite comprobar cómo se define la comparación con nulo:

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 
Así

se puede utilizar 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) ... 
3

¿Sólo piensas en bool? como tener 3 valores, entonces las cosas se ponen más fácil:

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

Si sólo desea probar para true contra null/false, que acabo acostumbrado y lee bastante bien es

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