Sie schreiben einen booleschen Ausdruck, der folgendermaßen aussehen könnte:
team.Category == "A Team" && team?.Manager?.IsVietnamVet
public class Manager
{
public bool IsVietnamVet { get; set; }
}
public class Team
{
public string Category { get; set; }
public Manager Manager { get; set; }
}
... und Sie erhalten eine Fehlermeldung:
Der Operator '&&' kann nicht auf Operanden vom Typ 'bool' und 'bool?'
Was ist der optimale / sauberste Weg, damit umzugehen?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet ?? false)
Ist das wirklich lesbar?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet).GetValueOrDefault()
In LINQ-to-Entities funktioniert dies möglicherweise nicht ...
team.Category == "A Team" && team?.Manager?.IsVietnamVet == true
Würden Sie wirklich
if (condition == true)
ohne zu zögern schreiben ?
Gibt es noch andere Möglichkeiten? Ist es letztendlich besser zu schreiben:
team.Category == "A Team" && team.Manager != null && team.Manager.IsVietnamVet
team.Manager?.IsVietnamVet
, dh keine nullbedingte Folgeteam
, da dies bereits nicht möglich istnull
.nullableBool == true
testet im Grunde genommennullableBool != false && nullableBool != null
(und es ist dieser zweite Teil, der es nützlich und daher nicht überflüssig macht)nullableBool == true
wenn ich keinen Wrapper erstelle. Es ist lesbar, da Sie normalerweise nicht schreiben,== true
wenn Sie einen regulären Booleschen Wert verwenden, wie @Flater erwähnt. Daher wird vorgeschlagen, dass die Variable nullwertfähig ist. Darüber hinaus wird die LINQ-Lesbarkeit verbessert, da Sie nicht mehrere Nullbedingungen verwenden, wie @Fabio erwähnt.Antworten:
In diesem speziellen Fall kann es ratsam sein, das Gesetz von Demeter zu befolgen, d. H.
Wenn ein boolescher Ausdruck komplex oder hässlich ist, gibt es nichts zu sagen, dass Sie ihn (oder einen Teil davon) nicht in eine separate Anweisung aufteilen können:
Wenn Sie den Code im Debugger durchgehen, ist es oft besser, ausgefeilte Bedingungen in einer einzigen
bool
zu packen, um ein wenig Mouseover-Hovering zu vermeiden. In der Tat könnte es einfacher sein, das Ganze in einebool
Variable zu setzen.oder mit LINQ:
quelle
a && b && c &&...
nacheinander ausgeführt werden und die nächste nicht einmal ausgeführt wird, wenn die vorherige ausgeführt wirdfalse
. Die Leute setzen also normalerweise am Anfang am schnellsten. Denken Sie daran, wenn Sie Sachen in eine separate Bool-VarIsManagerVietnamVet
Eigenschaft in einer DatenbankIch denke, Option 3 (dh
== true
) ist der sauberste Weg, um zu testen, ob abool?
isttrue
, weil es sehr klar ist , was es tut.In den meisten Fällen
x == true
macht Code keinen Sinn, weil es das gleiche ist wiex
, aber das gilt hier nicht, also denke ich,== true
wäre nicht sehr verwirrend.quelle
a?.b == true
, dass er verwirrt ist, aber sobald er versteht, was er tut, wird es zu einer sehr lesbaren Redewendung, viel schöner, als!= null
mitten in einem komplexen Ausdruck testen zu müssen . Gleiches gilt füra?.b ?? false
, was als beliebteste Lösung an Bedeutung gewonnen zu haben scheint, da es mit dem übereinstimmt, was Sie eingeben würden, wenn Sie mit einem anderen Typ als Boolean arbeiten würden [obwohl ich es für Boolean nicht mag; für mich liest es sich nicht so natürlich; Ich bevorzuge== true
].Wenn Sie die Antwort von Ben Cottrell erweitern, kann Ihnen das Muster "Null Object" weiterhelfen.
Anstatt ein
null
Team / einen Manager zurückzugeben, extrahierenITeam
undIManager
verbinden Sie und geben Sie sinnvolle alternative Implementierungen zurück:Dann können Sie plötzlich
team.ManagedByVietnamVet
sicher tun .Dies setzt natürlich voraus, dass der Upstream-Anbieter
team
null-sicher ist - dies kann jedoch durch entsprechende Tests sichergestellt werden.quelle
Ich habe eine einfache Klasse geschrieben, die Sie verwenden können:
Wenn es zuverlässig ist, einen benutzerdefinierten Typ zu verwenden, natürlich. Sie können
MyBool
mit beidenbool
und vergleichenNullable<bool>
.quelle