Der beste Weg, um in einem Bedingungsausdruck nach nullbarem Bool zu suchen (wenn…)


207

Ich habe mich gefragt, was die sauberste und verständlichste Syntax für die Durchführung von Bedingungsprüfungen für nullfähige Bools ist.

Ist der folgende gute oder schlechte Codierungsstil? Gibt es eine Möglichkeit, den Zustand besser / sauberer auszudrücken?

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

insbesondere der if (nullableBool ?? false) Teil. Ich mag den if (x.HasValue && x.Value)Stil nicht ...

(nicht sicher, ob die Frage schon einmal gestellt wurde ... konnte bei der Suche nichts Ähnliches finden)

Antworten:


361

Ich denke, viele Leute konzentrieren sich auf die Tatsache, dass dieser Wert nullbar ist, und denken nicht darüber nach, was sie tatsächlich wollen :)

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

Oder wenn Sie mehr Optionen möchten ...

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

(nullableBool == true)wird nie wahr zurückgeben, wenn der Bool? ist null: P.


2
Ich wusste nicht, dass ein nullbarer Vergleich so sinnvoll ist. Details finden Sie unter msdn.microsoft.com/en-us/library/2cf62fcy.aspx
Micah Zoltu

79

Wie wäre es mit GetValueOrDefault , das ziemlich selbsterklärend ist und es ermöglicht, jeden gewünschten Standard zu verwenden:

if (nullableBool.GetValueOrDefault(false)) {
}

6
Abhängig vom Kontext könnte dieser Ansatz werfenSystem.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
Ich mag diesen Ansatz, da er auch in einer Nicht-Wenn-Anweisung (dh Zuweisung) funktioniert.
Paultechguy

48

Sie mögen es vielleicht nicht, aber ich persönlich finde

if (x.HasValue && x.Value)

am besten lesbar. Es macht deutlich, dass Sie mit einem nullbaren Typ arbeiten, und es macht deutlich, dass Sie zuerst prüfen, ob der nullbare Typ einen Wert hat, bevor Sie bedingt darauf reagieren.

Wenn Sie Ihre Version nehmen und die Variable durch x ersetzen, lautet sie auch:

if (x ?? false)

Ist das so klar? Ist es offensichtlich, dass x ein nullbarer Typ ist? Ich werde dich entscheiden lassen.


so viel ich weiss, ?? funktioniert nur bei nullbaren Typen. Plus die Variable sollte einen schöneren Namen als x haben :)
FireSnake

5
Mit "nullbarer Typ" meinte ich speziell System.Nullable-Typen. Jeder Referenztyp kann null sein. Wenn Sie den Typ einer Variablen als Teil ihres Namens verwenden müssen, ist dies ein Hinweis darauf, dass Ihr Code nicht klar ist.
Dan Diplo

@DanDiplo Wie schreibe ich UT dafür?
Prashant Yadav

xist im Kontext in Ordnung und manchmal sauberer; zu wissen:var openOrders = orders.Where(x=>x.Open ?? false)
nichts ist

21

Wenn Sie a nullals falsch behandeln möchten, würde ich sagen, dass der prägnanteste Weg, dies zu tun, die Verwendung des Null-Koaleszenz-Operators ( ??) ist, wie Sie beschreiben:

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

8

Denken Sie nur an Bool? Wenn Sie 3 Werte haben, wird es einfacher:

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

8

Verwenden Sie Erweiterungen.

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
}

Was ist, wenn Sie zu prüfen, nullwie true?
Thibault Falise

IsTrue () | IsNull () .. :) Ich habe die Logik reproduziert, wie SQL mit Nullen funktioniert. Ich denke, es ist die sauberste und verständlichste Syntax.
Andrey Frolov

Es sollte ein öffentlicher statischer Bool sein. IsFalse (this System.Nullable val) {return! Val ?? wahr; } Null als falsch zu betrachten
Michael Freidgeim

2
Möglicherweise fehlen Semikolons (;) in den letzten beiden Methoden (dh IsNull und IsNotNull)
Glenn Garson

4

Überprüfen wir, wie der Vergleich mit null definiert ist:

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

und die Ergebnisse sind:

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

So können Sie sicher verwenden:

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

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

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

Ich frage mich nur, warum wir nicht tun können, wenn (nullbar) ... das wäre Handle, muss aber mit Vorsicht behandelt werdenif(nullable)...else if(!nulllable)...else..
IronHide

Ich würde sagen, dass in den letzten Jahren der Codierungsstil (aufgrund der Verfügbarkeit von Tools wie Stylecop, Analysatoren usw.) immer mehr eindeutigen, klaren Code zur Bestätigung der Absicht bevorzugt (z. B. die Empfehlung, nicht benötigte Klammern zu verwenden, um die beabsichtigte Verwendung zu bestätigen der Betreiberpriorität oder unter Verwendung verschiedener Anmerkungs- / Vertragssysteme). Die Einführung einer solchen Syntax durch die IMO würde aufgrund der Unklarheit im Umgang mit Nullables viel mehr Verwirrung stiften als den Nutzen.
Gr. Moncz

4

Eigentlich denke ich, dass dies (nullableBool ?? false)eine legitime Option ist, insbesondere wenn Sie versuchen, einen nullbaren Bool in linq auszuwerten.

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

Ist meiner Meinung nach sauberer im Gegensatz zu:
array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)


1

Wenn Sie nur truegegen null/ testen möchten false, ist eine, die ich gerade verwendet habe und die recht gut liest, eine

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

1
Erhalten Sie hier keine Nullreferenzausnahme?
Chase Florell

@ChaseFlorell Ich musste dies im VS Interactive-Fenster überprüfen. Beachten Sie also, dass der Typ einer Bedingung Nullable <bool> ist. Sie können die von object (z. B. Equals), HasValue und GetValueOrDefault geerbten Methoden weiterhin aufrufen , aber nicht Wert
ds4940

Interessant, das kann ich jetzt sehen. Noch skizzenhaft für Referenztypen dotnetfiddle.net/8cAI21
Chase Florell

0

Ich denke, es liegt an dir. Ich denke sicherlich, dass der .HasValue-Ansatz besser lesbar ist, insbesondere bei Entwicklern, die mit dem ?? Syntax.

Der andere Punkt eines nullbaren booleschen Typs ist, dass er tristate ist. Sie möchten also möglicherweise etwas anderes tun, wenn er nur null ist und nicht standardmäßig false.


0

Enum gegeben

public enum PublishMode { Edit, View }

Sie können es wie hier tun

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

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

Keine Antwort auf die Frage, um die es speziell geht nullable boolean.
ToolmakerSteve

0

Wenn Sie sich in einer Situation befinden, in der Sie keine Kontrolle darüber haben, ob ein Teil der Bedingung einen nullbaren Wert überprüft, können Sie immer Folgendes versuchen:

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

Ich weiß, dass es nicht gerade ein puristischer Ansatz ist, ein Ternär in eine if-Anweisung einzufügen, aber es löst das Problem sauber.

Dies ist natürlich eine manuelle Art zu sagen GetValueOrDefault(false)


3
Die im OP bereitgestellte Lösung ist dieselbe, jedoch mit weitaus weniger aufgeblähtem Code. Das ist dafür überhaupt nicht vorteilhaft.
Servy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.