Wiem, że standardowym sposobem używania operatora koalescencji Null w C # jest ustawienie wartości domyślnych.
string nobody = null;
string somebody = "Bob Saget";
string anybody = "";
anybody = nobody ?? "Mr. T"; // returns Mr. T
anybody = somebody ?? "Mr. T"; // returns "Bob Saget"
Ale do czego jeszcze można ??
wykorzystać? Nie wydaje się tak użyteczny jak operator trójskładnikowy, poza tym, że jest bardziej zwięzły i łatwiejszy do odczytania niż:
nobody = null;
anybody = nobody == null ? "Bob Saget" : nobody; // returns Bob Saget
Więc biorąc pod uwagę, że mniej nawet wie o zerowym operatorze koalescencji ...
Czy używałeś
??
czegoś innego?Jest to
??
konieczne lub po prostu użyj operatora trójskładnikowego (który większość zna)
c#
coding-style
null
conditional-operator
null-coalescing-operator
Armstrongest
źródło
źródło
Użyłem go jako linijki z leniwym ładowaniem:
Czytelny? Zdecyduj sam.
źródło
Uważam, że jest przydatny na dwa „nieco dziwne” sposoby:
out
parametru podczas pisaniaTryParse
procedur (tj. Zwraca wartość null, jeśli parsowanie nie powiedzie się)Ten ostatni potrzebuje trochę więcej informacji. Zwykle, gdy tworzysz porównanie z wieloma elementami, musisz sprawdzić, czy pierwsza część porównania (np. Wiek) daje ostateczną odpowiedź, a następnie następna (np. Imię) tylko wtedy, gdy pierwsza część nie pomogła. Używanie operatora łączenia wartości null oznacza, że możesz pisać całkiem proste porównania (czy to w celu uporządkowania, czy równości). Na przykład, używając kilku klas pomocniczych w MiscUtil :
Wprawdzie mam teraz ProjectionComparer w MiscUtil, wraz z kilkoma rozszerzeniami, które sprawiają, że tego rodzaju rzeczy są jeszcze łatwiejsze - ale nadal jest fajne.
To samo można zrobić, aby sprawdzić równość odwołań (lub nieważność) na początku implementowania Equals.
źródło
Kolejną zaletą jest to, że operator trójskładnikowy wymaga podwójnej oceny lub zmiennej tymczasowej.
Rozważmy to na przykład:
podczas gdy z operatorem trójskładnikowym pozostaje:
która dwukrotnie wywołuje MyMethod lub:
Tak czy inaczej, operator koalescencji zerowej jest czystszy i, jak sądzę, bardziej wydajny.
źródło
MyMethod()
ma jakiekolwiek skutki uboczne.MyMethod()
nie ma żadnych efektów poza zwracaniem wartości, kompilator wie, aby nie wywoływać jej dwukrotnie, więc w większości przypadków nie musisz się martwić o wydajność.MyMethod()
jest to połączona sekwencja kropkowanych obiektów. Np .:myObject.getThing().getSecondThing().getThirdThing()
MyMethod
są identyczne w tym kontekście, zakładając, żeMyMethod
jest to funkcja Pure. Inną opcją jest Automatyczne zapamiętywanie lub po prostu zamknięcie funkcji w pamięci podręcznej. Z drugiej strony: en.wikipedia.org/wiki/Global_value_numberingInną rzeczą do rozważenia jest to, że operator koalescencji nie wywołuje metody get właściwości dwukrotnie, jak robi to trójskładnik.
Są więc scenariusze, w których nie powinieneś używać trójskładnika, na przykład:
Jeśli użyjesz:
getter zostanie wywołany dwukrotnie, a
count
zmienna będzie równa 2, a jeśli użyjesz:count
zmienna będzie równa 1, jak powinno.źródło
??
jest równoważny do?:
.Największą zaletą, jaką widzę dla
??
operatora, jest to, że można łatwo przekonwertować typy wartości dopuszczające wartość null na typy nieprzekraczające wartości null:Często używam tego w zapytaniach Linq:
źródło
kvp == null
. I faktycznieNullable<T>
maGetValueOrDefault
metodę, której normalnie używam.Użyłem ?? w mojej implementacji IDataErrorInfo:
Jeśli jakaś właściwość jest w stanie „błędu”, otrzymuję ten błąd, w przeciwnym razie otrzymuję wartość null. Działa naprawdę dobrze.
źródło
this["Name"]
,this["Address"]
itp ??Możesz użyć operatora koalescencji null, aby uczynić go nieco czystszym w obsłudze przypadku, w którym opcjonalny parametr nie jest ustawiony:
źródło
arg ?= Arg.Default
?Lubię używać operatora koalescencji zerowej do leniwego ładowania niektórych właściwości.
Bardzo prosty (i wymyślony) przykład, aby zilustrować mój punkt widzenia:
źródło
Właściwie, z mojego doświadczenia wynika, że zbyt mało osób zna operator trójskładnikowy (a dokładniej operator warunkowy ;
?:
jest „trójskładnikowy” w tym samym sensie, co||
binarny lub+
jednoargumentowy lub binarny; jednak zdarza się, że jest to tylko operator trójskładnikowy w wielu językach), więc przynajmniej w tej ograniczonej próbce twoja instrukcja zawodzi.Ponadto, jak wspomniano wcześniej, istnieje jedna poważna sytuacja, w której operator koalescencji zerowej jest bardzo przydatny, a jest to ilekroć oceniane wyrażenie ma jakiekolwiek skutki uboczne. W takim przypadku nie można użyć operatora warunkowego bez (a) wprowadzenia zmiennej tymczasowej lub (b) zmiany rzeczywistej logiki aplikacji. (b) jest wyraźnie nieodpowiednie w żadnych okolicznościach i chociaż jest to osobiste preferencje, nie lubię zaśmiecać zakresu deklaracji wieloma zewnętrznymi, nawet krótkotrwałymi, zmiennymi, więc (a) też jest w tym szczególny scenariusz.
Oczywiście, jeśli musisz przeprowadzić wielokrotne sprawdzenie wyniku,
if
prawdopodobnie narzędziem do tego zadania jest operator warunkowy lub zestaw bloków. Ale dla prostego „jeśli to jest null, użyj tego, w przeciwnym razie użyj tego”, operator koalescencji zerowej??
jest doskonały.źródło
Jedną z rzeczy, które ostatnio często robiłem, jest koalescencja zerowa do tworzenia kopii zapasowych
as
. Na przykład:Jest to również przydatne do tworzenia kopii zapasowych długich łańcuchów, z
?.
których każdy może zawieśćźródło
Jedynym problemem jest to, że operator łączenia zerowego nie wykrywa pustych ciągów.
to znaczy
WYNIK:
Obecnie pracuję nad zastąpieniem ?? operator, aby obejść ten problem. Z pewnością przydałoby się mieć to wbudowane w Framework.
Myśli?
źródło
??
nie może być przeciążony: msdn.microsoft.com/en-us/library/8edha89s(v=vs.100).aspx - byłoby jednak świetnie, gdyby można było go przeciążać. Używam kombinacji:s1.Nullify() ?? s2.Nullify()
gdziestring Nullify(this s)
zwraca anull
w przypadkach, gdy ciąg jest pusty.Powinieneś używać tego, co najlepiej wyraża twoje zamiary. Ponieważ nie jest operatorem COALESCE null, używać go .
Z drugiej strony, ponieważ jest tak wyspecjalizowany, nie sądzę, aby miał inne zastosowania. Wolałbym odpowiednie przeciążenie
||
operatora, tak jak robią to inne języki. Byłoby to bardziej oszczędne w projekcie języka. Ale cóż…źródło
Chłodny! Policz mnie jako kogoś, kto nie wiedział o zerowym operatorze koalescencji - to całkiem fajna rzecz.
Uważam, że jest dużo łatwiejszy do odczytania niż operator trójskładnikowy.
Pierwszym miejscem, które przychodzi mi na myśl, gdzie mógłbym go użyć, jest przechowywanie wszystkich moich domyślnych parametrów w jednym miejscu.
źródło
Trochę dziwny przypadek użycia, ale miałem metodę, w której
IDisposable
obiekt jest potencjalnie przekazywany jako argument (i dlatego usuwany przez rodzica), ale może być również pusty (i dlatego powinien zostać utworzony i usunięty w metodzie lokalnej)Aby go użyć, kod wyglądał jak
Ale z zerowym połączeniem staje się znacznie schludniejszy
źródło
Użyłem w ten sposób:
źródło