Il modo migliore per verificare la presenza di valori boollegabili nulla in un'espressione condizione (se ...)


208

Mi chiedevo quale fosse la sintassi più pulita e comprensibile per fare i controlli delle condizioni sui bool di nullable.

Il seguente stile di codifica è buono o cattivo? C'è un modo per esprimere la condizione in modo migliore / più pulito?

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

in particolare la parte if (nullableBool ?? false) . Non mi piace lo if (x.HasValue && x.Value)stile ...

(non sono sicuro se la domanda sia stata posta prima ... non è stato possibile trovare qualcosa di simile con la ricerca)

Risposte:


362

Penso che molte persone si concentrino sul fatto che questo valore è nullable e non pensano a ciò che vogliono effettivamente :)

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

O se vuoi più opzioni ...

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

(nullableBool == true)non tornerà mai vero se il bool? è null: P


2
Non mi rendevo conto che il confronto nullable fosse significativo come questo. I dettagli sono disponibili all'indirizzo msdn.microsoft.com/en-us/library/2cf62fcy.aspx
Micah Zoltu,

79

Che ne dici di usare GetValueOrDefault , che è piuttosto autoesplicativo e ti permette di usare qualunque impostazione predefinita tu voglia:

if (nullableBool.GetValueOrDefault(false)) {
}

6
A seconda del contesto che questo approccio potrebbe lanciareSystem.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
Mi piace questo approccio in quanto funziona anche in un'istruzione non if (ovvero assegnazione).
paultechguy,

48

Potrebbe non piacerti, ma personalmente lo trovo

if (x.HasValue && x.Value)

il più leggibile. Indica chiaramente che stai lavorando con un tipo nullable e chiarisce che stai prima verificando se il tipo nullable ha un valore prima di agire in modo condizionale.

Se prendi la tua versione e sostituisci la variabile con x, si legge anche:

if (x ?? false)

È chiaro? È ovvio x è un tipo nullable? Ti lascio decidere.


per quanto ne so, ?? funziona solo su tipi nullable. Inoltre, la variabile dovrebbe avere un nome più bello di x :)
FireSnake,

5
Per "tipo nullable" intendevo specificamente i tipi System.Nullable. Qualsiasi tipo di riferimento può essere nullo. Inoltre, se devi usare il tipo di una variabile come parte del suo nome, questo è indicativo che il tuo codice non è chiaro.
Dan Diplo,

@DanDiplo Come scrivere UT per questo?
Prashant Yadav,

xva bene nel contesto e talvolta è più pulito; vale a dire:var openOrders = orders.Where(x=>x.Open ?? false)
nulla è necessario il

21

Se vuoi trattare un nullcome falso, direi che il modo più succinto per farlo è usare l'operatore null coalesce ( ??), come descrivi:

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

8

Pensi solo a bool? come avere 3 valori, quindi le cose diventano più facili:

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

8

Usa le estensioni.

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
}

E se si desidera considerare nullcome true?
Thibault Falise,

IsTrue () | IsNull () .. :) Ho riprodotto la logica di come SQL funziona con i null. Penso che sia la sintassi più pulita e comprensibile.
Andrey Frolov,

Dovrebbe essere pubblico bool statico IsFalse (questo System.Nullable val) {return! Val ?? vero; } considerare null come falso
Michael Freidgeim,

2
Potrebbero mancare i punti e virgola (;) negli ultimi due metodi (cioè IsNull e IsNotNull)
glenn garson,

4

Consente di verificare come viene definito il confronto 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}");
    }

e i risultati sono:

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

Quindi puoi usare in sicurezza:

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

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

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

Mi sto solo chiedendo perché non possiamo fare se (nullable) .... sarebbe gestibile ma deve essere trattato con cautelaif(nullable)...else if(!nulllable)...else..
IronHide,

Direi che negli ultimi anni lo stile di codifica (a causa della disponibilità di strumenti come stylecop, analizzatori, ecc.) Preferisce sempre più il codice inequivocabile, chiaro, di "intenzione di conferma" (ad es. Raccomandare di usare parentesi non necessarie solo per confermare l'uso previsto di priorità degli operatori o utilizzando vari sistemi di annotazione / contratto). L'introduzione di una tale sintassi da parte dell'IMO causerebbe molta più confusione a causa del livello di chiarezza su come vengono gestiti i nullable che sui benefici.
Sz. Moncz,

4

In realtà penso che (nullableBool ?? false)sia un'opzione legittima soprattutto quando stai cercando di valutare un bool nulla in Linq.

Per esempio:
array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

Secondo me è più pulito rispetto a:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)


1

Se vuoi solo provare truecontro null/ false, quello che ho appena usato e che legge abbastanza bene lo è

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

1
Non stai ottenendo un'eccezione di riferimento null qui?
Chase Florell,

@ChaseFlorell Ho dovuto ricontrollare questo nella finestra VS Interactive. Quindi la cosa da ricordare è che il tipo di condizione è Nullable <bool>. Puoi ancora chiamare i metodi ereditati dall'oggetto (come Equals), HasValue e GetValueOrDefault , ma non valore
ds4940,

interessante, posso vederlo ora. Ancora abbozzato per i tipi di riferimento dotnetfiddle.net/8cAI21
Chase Florell,

0

Penso che dipenda da te. Penso certamente che l'approccio .HasValue sia più leggibile, specialmente con gli sviluppatori che non hanno familiarità con ?? sintassi.

L'altro punto di un tipo booleano nullable è che è tristato, quindi potresti voler fare qualcos'altro quando è solo null, e non predefinito su false.


0

Dato enum

public enum PublishMode { Edit, View }

puoi farlo come qui

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

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

Non una risposta alla domanda, che riguarda specificamente nullable boolean.
ToolmakerSteve

0

Se ti trovi in ​​una situazione in cui non hai il controllo sul fatto che parte della condizione stia verificando un valore nullable, puoi sempre provare quanto segue:

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

So che non è esattamente un approccio purista che inserisce un ternario in un'istruzione if, ma risolve il problema in modo chiaro.

Questo è, ovviamente, un modo di dire manuale GetValueOrDefault(false)


3
La soluzione fornita nel PO è la stessa cosa, ma solo con un numero di blocchi di codice molto inferiore. Questo non è affatto vantaggioso.
Servisce il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.