Meilleure façon de vérifier le booléen nullable dans une expression de condition (si…)

208

Je me demandais quelle était la syntaxe la plus claire et la plus compréhensible pour faire des vérifications de condition sur les bools nullables.

Le style de codage suivant est-il bon ou mauvais? Existe-t-il un moyen d'exprimer la condition mieux / plus proprement?

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

en particulier la partie if (nullableBool ?? false) . Je n'aime pas le if (x.HasValue && x.Value)style ...

(Je ne sais pas si la question a déjà été posée ... je n'ai pas trouvé quelque chose de similaire avec la recherche)

FireSnake
la source

Réponses:

362

Je pense que beaucoup de gens se concentrent sur le fait que cette valeur est nulle, et ne pensent pas à ce qu'ils veulent réellement :)

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

Ou si vous voulez plus d'options ...

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

(nullableBool == true)ne reviendra jamais vrai si le bool? est nul: P

Artiom Chilaru
la source
2
Je ne savais pas que la comparaison annulable était significative comme ça. Les détails peuvent être trouvés à msdn.microsoft.com/en-us/library/2cf62fcy.aspx
Micah Zoltu
79

Que diriez-vous d'utiliser GetValueOrDefault , qui est assez explicite et permet d'utiliser la valeur par défaut que vous souhaitez:

if (nullableBool.GetValueOrDefault(false)) {
}
Lucero
la source
6
Selon le contexte que cette approche pourrait jeterSystem.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
J'aime cette approche car elle fonctionne également dans une instruction non-if (c.-à-d. Affectation).
paultechguy
48

Vous ne l'aimez peut-être pas, mais personnellement, je trouve

if (x.HasValue && x.Value)

le plus lisible. Il indique clairement que vous travaillez avec un type nullable et il est clair que vous vérifiez d'abord si le type nullable a une valeur avant d'agir de manière conditionnelle.

Si vous prenez votre version et remplacez la variable par x, elle indique également:

if (x ?? false)

Est-ce aussi clair? Est-il évident que x est un type nullable? Je vous laisse décider.

Dan Diplo
la source
Autant que je sache, ?? ne fonctionne que sur les types nullables. De plus, la variable devrait avoir un nom plus agréable que x :)
FireSnake
5
Par "type nullable", j'entendais spécifiquement les types System.Nullable. Tout type de référence peut être nul. De plus, si vous devez utiliser le type d'une variable dans le cadre de son nom, cela indique que votre code n'est pas clair.
Dan Diplo
@DanDiplo Comment écrire UT pour cela?
Prashant Yadav
xest bien dans son contexte et est parfois plus propre; à savoir:var openOrders = orders.Where(x=>x.Open ?? false)
rien n'est nécessaire
21

Si vous voulez traiter un nullcomme faux, je dirais que la façon la plus succincte de le faire est d'utiliser l'opérateur de coalescence nulle ( ??), comme vous le décrivez:

if (nullableBool ?? false) { ... }
Oded
la source
8

Pensez juste à bool? comme ayant 3 valeurs, alors les choses deviennent plus faciles:

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

la source
8

Utilisez des extensions.

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
}
Andrey Frolov
la source
Que faire si vous voulez considérer nullcomme true?
Thibault Falise
IsTrue () | IsNull () .. :) J'ai reproduit la logique de fonctionnement de SQL avec les valeurs nulles. Je pense que c'est la syntaxe la plus claire et la plus compréhensible.
Andrey Frolov
Il doit s'agir d'un bool statique public IsFalse (ce System.Nullable val) {return! Val ?? vrai; } considérer null comme faux
Michael Freidgeim
2
Il peut manquer des points-virgules (;) dans les deux dernières méthodes (c.-à-d. IsNull et IsNotNull)
glenn garson
4

Permet de vérifier comment la comparaison avec null est définie:

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

et les résultats sont:

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

Vous pouvez donc utiliser en toute sécurité:

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

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

// check if true or false
if (nullable != null) ...
Sz. Moncz
la source
Je me demande juste pourquoi ne pouvons-nous pas le faire si (annulable) .... ce serait à gérer mais doit être traité avec prudenceif(nullable)...else if(!nulllable)...else..
IronHide
Je dirais qu'au cours des dernières années, le style de codage (en raison de la disponibilité d'outils tels que stylecop, analyseurs, etc.) préfère de plus en plus un code sans ambiguïté, clair et "confirmant l'intention" (par exemple, recommander d'utiliser des parenthèses inutiles juste pour confirmer l'utilisation prévue priorité des opérateurs, ou en utilisant divers systèmes d'annotation / contrat). L'OMI introduisant une telle syntaxe causerait beaucoup plus de confusion en raison du niveau de manque de clarté de la façon dont les nullables sont traités que d'avantages.
Sz. Moncz
4

En fait, je pense que (nullableBool ?? false)c'est une option légitime, surtout lorsque vous essayez d'évaluer un bool nullable dans linq.

Par exemple:
array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

Est plus propre à mon avis que:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)

Zze
la source
1

Si vous voulez seulement tester pour truecontre null/ false, celui que je viens d'utiliser et qui lit assez bien est

bool? someCondition = null
if (someCondition.Equals(true))
...
ds4940
la source
1
N'obtenez-vous pas une exception de référence nulle ici?
Chase Florell
@ChaseFlorell J'ai dû vérifier ceci dans la fenêtre VS Interactive .. Donc, la chose à retenir est que le type de condition est Nullable <bool> .Vous pouvez toujours appeler les méthodes héritées de l'objet (telles que Equals), HasValue et GetValueOrDefault , mais pas de valeur
ds4940
intéressant, je peux le voir maintenant. Encore incomplet pour les types de référence dotnetfiddle.net/8cAI21
Chase Florell
0

Je pense que ça dépend de vous. Je pense certainement que l'approche .HasValue est plus lisible, en particulier avec les développeurs qui ne connaissent pas ?? syntaxe.

L'autre point d'un type booléen nullable est qu'il est tristate, donc vous voudrez peut-être faire quelque chose d'autre quand il est juste null, et non par défaut false.

James Westgate
la source
0

Étant donné l'énumération

public enum PublishMode { Edit, View }

vous pouvez le faire comme ici

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

//or
       if (mode?? PublishMode.Edit == someValue)
       ....
    }
Gopher
la source
Pas une réponse à la question, qui concerne spécifiquement nullable boolean.
ToolmakerSteve
0

Si vous êtes dans une situation où vous ne contrôlez pas si une partie de la condition vérifie une valeur annulable, vous pouvez toujours essayer ce qui suit:

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

Je sais que ce n'est pas exactement une approche puriste mettant un ternaire dans une déclaration if, mais cela résout le problème proprement.

C'est, bien sûr, une façon manuelle de dire GetValueOrDefault(false)

MetalPhoenix
la source
3
La solution fournie dans l'OP est la même chose, mais avec beaucoup moins de ballonnement de code. Ce n'est pas du tout avantageux pour cela.
Servy