Null coalescing operator, null-conditional operator, ternary conditional operator, nullable type, czyli wszystko o ? znaku zapytania w składni języka C# powinieneś wiedzieć.
#1 Nullable Type
Pierwsze najbardziej popularne wykorzystanie – nullable property
– właściwość która może przyjmować wartość null
. Warto tu zwrócić uwagę na domyślne wartości po stworzeniu nowego obiektu HouseAddress
->
- ApartmentNumber –
null
- HouseNumber –
0
- HouseNumber StreetName =
null
#2 Null Coalescing
Kolejnym zastosowaniem jest operator scalania (null-coalescing operator) ??
, który w przypadku gdy wartość po jego lewej stronie jest nullem, odwołuje się do wartości po operatorze. Może to być wartość domyślna (tzw default lub fallback) lub w przypadku gdy wartość jest przez nas wymagana, można rzucić wyjątkiem.
Działanie operatora przedstawiam Tobie na poniższym przykładzie, w raz z wartościami wypisanymi przez konsolę.
#3 Null Conditional
A co jeśli to obiekt address
przekazany do naszej metody będzie `null`? W powyższych przypadkach z pewnością czeka Ciebie NullReferenceException – wyjątek rzucany w momencie odwołania się do obiektu o wartości null. Z rozwiązaniem przychodzi oczywiście ? jako operator warunkowego dostępu.
Idea działania przedstawiona poniżej (address?):
#4 Null-Coalescing Assignment
Wracając jeszcze do operatora scalania, bardzo przydatnym rozwiązaniem jest połączenie przypisania i scalania ??= (null-coalescing assignment). Załóżmy, że nasza metoda jest wielokrotnie wywoływana i z jakiegoś względu nie mamy pewności, że address
zostanie załadowany/przekazany i może przyjąć wartość null
. Na szczęście dysponujemy danymi, pozwalającymi nam dociągnąć ten adres – metoda `GetAddress()`. Rozpatrzmy 3 przypadki rozwiązania:
- 1 – sprawdzamy czy
address
ma wartość null, a następnie wywołujemy metodęGetAddress()
- 2 – tworzymy dodatkową zmienną
myAddress
która przyjmuje wartośćaddress
jeśli nie jest nullem, lub rezultatu zwróconego przez metodęGetAddress()
- główne wady tego rozwiązania, to:
- nadmiarowa, nie potrzebna zmienna,
- pogorszenie czytelność kodu
- ryzyko niezamierzonego wykorzystania niewłaściwej zmiennej (
address
lubmyAddress
)
- główne wady tego rozwiązania, to:
No dobra, ktoś powie, że ta dodatkowe zmienna nie jest potrzebna, i można to zapisać w postaci #3. Analizujmy dalej:
- 3 – działa podobnie jak 2, z tą różnicą, że nie tworzy dodatkowej zmiennej
- 4 – i w tym momencie wchodzi ??= cały na biało – w przypadku gdy
address
ma wartość null, wywołana zostaje metodaGetAddress()
i przypisuje jej rezultat do zmiennejaddress
Warto zaznaczyć, że operatory scalania są prawostronnie skojarzone, czyli wyrażenia są rozpatrywane jak pokazuję poniżej:
a ?? b ?? c ---> a ?? (b ?? c)
d ??= e ??= f ---> d ??= (e ??= f)
#5 Ternary Conditional
Symbol ? dał się już poznać jako operator warunkowego dostępu, gdzie warunkowy jest słowem kluczem. Może posłużyć również do zastąpienia instrukcji warunkowej if/else
bardziej czytelną wersją (zadziała jeśli, po pierwsze się z tą składnią obędziesz, a po drugie nie będzie to zbyt zawiły kod), w postaci trójskładnikowej instrukcji warunkowej ?: (ternary conditional operator).
Rozpatrzmy abstrakcyjny przypadek warunkowego (includeStreetName
) dodania nazwy ulicy do adresu:
- 1 – z wykorzystaniem instrukcji warunkowej
if/else
zależnie od wartości true/fale otrzymamy2/3
lubProgramistyczna 2/3
- 2 – z zastosowaniem trójskładnikowej instrukcji warunkowej
- 3 – uproszczony kod z wersji 2
Jak sam pewnie zauważysz, wersja 3 może wydawać się mniej czytelna niż 2. Wszystko zależy od osobistych preferencji.
Operator ? – Podsumowanie
Jak widzisz, ?
ma dość liczne zastosowania w składni języka C#. Mam nadzieję, że udało mi się je przedstawić w zrozumiały i przystępny sposób.
Jeśli zainteresował Cię materiał, zapraszam do listy mailowej, by odebrać wartościowe bonusy i być na bieżąco z kolejnymi wpisami.