Piszesz wyrażenie logiczne, które może wyglądać następująco:
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; }
}
... i pojawia się błąd:
Operatora „&&” nie można stosować do operandów typu „bool” i „bool?”
Jaki jest optymalny / najczystszy sposób, aby sobie z tym poradzić?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet ?? false)
Czy to naprawdę czytelne?
team.Category == "A Team" && (team?.Manager?.IsVietnamVet).GetValueOrDefault()
Może nie działać w LINQ-to-Entities ...
team.Category == "A Team" && team?.Manager?.IsVietnamVet == true
Czy naprawdę napisałbyś
if (condition == true)
bez wahania?
Czy są jakieś inne opcje? Czy ostatecznie lepiej jest napisać:
team.Category == "A Team" && team.Manager != null && team.Manager.IsVietnamVet
team.Manager?.IsVietnamVet
, tzn. Później nie ma warunku nullteam
, ponieważ już nie może byćnull
.nullableBool == true
jest w zasadzie testowanie pod kątemnullableBool != false && nullableBool != null
(i ta druga część sprawia, że jest przydatna, a zatem nie jest zbyteczna)nullableBool == true
jeśli nie utworzę opakowania. Jest czytelny, ponieważ normalnie nie piszesz,== true
gdy używasz zwykłej wartości logicznej, jak wspomina @Flater, więc sugeruje, że zmienna ma wartość null. Dodatkowo poprawia to czytelność LINQ, ponieważ nie używasz wielu warunków zerowych, jak wspomina @Fabio.Odpowiedzi:
W tym konkretnym przypadku rozsądne może być przestrzeganie Prawa Demetera, tj
Mówiąc bardziej ogólnie, jeśli wyrażenie boolowskie jest złożone lub brzydkie, nie ma nic do powiedzenia, że nie można go podzielić (lub jego części) na osobne stwierdzenie:
Podczas przechodzenia przez kod w debuggerze często fajniej jest mieć rozbudowane warunki spakowane w jeden,
bool
aby zaoszczędzić trochę najechania kursorem myszy; w rzeczywistości lepiej byłoby umieścić całość wbool
zmiennej.lub z LINQ:
źródło
a && b && c &&...
są wykonywane sekwencyjnie, a następny nie jest nawet wykonywany, jeśli poprzedni jestfalse
. Dlatego ludzie zwykle stawiają na początku najszybciej. Miej to na uwadze, przenosząc rzeczy do osobnego bool-varIsManagerVietnamVet
właściwość przejdzie do sprawdzenia w bazie danych;)Myślę, że opcja 3 (tj.
== true
) Jest najczystszym sposobem sprawdzenia, czybool?
jesttrue
, ponieważ jest bardzo jasne, co robi.W większości kod
x == true
nie ma sensu, ponieważ jest taki sam jakx
, ale nie dotyczy to tutaj, więc myślę,== true
że nie byłoby to bardzo mylące.źródło
a?.b == true
że będą zdezorientowani, ale gdy zrozumieją, co robi, staje się bardzo czytelnym idiomem, znacznie ładniejszym niż konieczność testowania!= null
w środku złożonego wyrażenia. To samo dotyczya?.b ?? false
, które wydaje się zyskać na popularności jako najbardziej popularne rozwiązanie, ponieważ pasuje do tego, co wpisałeś, gdybyś miał do czynienia z typem innym niż boolean [choć nie podoba mi się to dla boolean; dla mnie nie czyta się tak naturalnie; Wolę== true
].Rozwijając odpowiedź Bena Cottrella, wzór „Null Object” może ci pomóc.
Zamiast zwracać
null
zespół / menedżera, wyodrębnijITeam
iIManager
interfejsy oraz zwróć sensowne alternatywne implementacje:Nagle możesz to zrobić
team.ManagedByVietnamVet
bezpiecznie.To oczywiście zależy od dostawcy,
team
który ma być zerowo bezpieczny - ale można to zapewnić za pomocą odpowiednich testów.źródło
Napisałem prostą klasę, której możesz użyć:
Oczywiście niezawodne jest użycie niestandardowego typu. Możesz porównać
MyBool
z obubool
iNullable<bool>
.źródło