Przebiegł przez ten wiersz kodu:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Co oznaczają dwa znaki zapytania, czy jest to jakiś trójskładnikowy operator? W Google trudno jest szukać.
c#
null-coalescing-operator
Edward Tanguay
źródło
źródło
Odpowiedzi:
Jest to zerowy operator koalescencyjny i całkiem podobny do operatora trójskładnikowego (natychmiast-jeśli). Zobacz także ? Operator - MSDN .
rozwija się do:
co dalej rozwija się do:
W języku angielskim oznacza to: „Jeśli cokolwiek jest po lewej stronie, nie jest zerowe, użyj tego, w przeciwnym razie użyj tego, co jest po prawej stronie”.
Pamiętaj, że możesz użyć dowolnej ich liczby po kolei. Poniższe oświadczenie przydzieli pierwsze niezerowe
Answer#
doAnswer
(jeśli wszystkie odpowiedzi są nieważne, toAnswer
jest null):Warto również wspomnieć, podczas gdy powyższe rozwinięcie jest koncepcyjnie równoważne, wynik każdego wyrażenia jest oceniany tylko raz. Jest to ważne, jeśli na przykład wyrażenie jest wywołaniem metody z efektami ubocznymi. (Podziękowania dla @Joey za zwrócenie na to uwagi.)
źródło
??
jest skojarzony, więca ?? b ?? c ?? d
jest równoważny z((a ?? b) ?? c ) ?? d
. „Operatory przypisania i operator trójskładnikowy (? :) są prawymi asocjacjami. Wszystkie pozostałe operatory binarne pozostają asocjatywne”. Źródło: msdn.microsoft.com/en-us/library/ms173145.aspxTylko dlatego, że nikt inny nie wypowiedział jeszcze magicznych słów: to zerowy operator koalescencyjny . Jest zdefiniowany w sekcji 7.12 specyfikacji języka C # 3.0 .
Jest bardzo przydatny, szczególnie ze względu na sposób działania, gdy jest używany wielokrotnie w wyrażeniu. Wyrażenie formy:
poda wynik wyrażenia,
a
jeśli nie ma wartości null, w przeciwnym razie spróbujb
, w przeciwnym razie spróbujc
, w przeciwnym razie spróbujd
. W każdym punkcie powoduje zwarcie.Ponadto, jeśli typ
d
nie ma wartości zerowej, typ całego wyrażenia również nie ma wartości zerowej.źródło
To zerowy operator koalescencyjny.
http://msdn.microsoft.com/en-us/library/ms173224.aspx
Tak, prawie niemożliwe do wyszukania, chyba że wiesz, jak się nazywa! :-)
EDYCJA: I to jest fajna funkcja z innego pytania. Możesz je połączyć.
Ukryte funkcje C #?
źródło
Dziękujemy wszystkim, oto najbardziej zwięzłe wyjaśnienie, które znalazłem na stronie MSDN:
źródło
-1
jest po prostu zwykłąint
, która nie jest zerowalna).x
jest typuint?
, aley
jest typuint
, możesz napisaćint y = (int)(x ?? -1)
. Będzie analizowaćx
doint
jeśli nie jestnull
, lub przypisać-1
doy
jeżelix
jestnull
.??
służy do podania wartości typu zerowalnego, gdy wartość jest równa null. Zatem jeśli formAuth ma wartość NULL, zwróci nową FormsAuthenticationWrapper ().źródło
Dwa znaki zapytania (??) wskazują, że jest to operator koalescencyjny.
Operator koalescencji zwraca pierwszą wartość NON-NULL z łańcucha. Możesz obejrzeć ten film na youtube, który praktycznie pokazuje całą sprawę.
Ale pozwól mi dodać więcej do tego, co mówi film.
Jeśli widzisz angielskie znaczenie koalescencji, to mówi „konsoliduj razem”. Na przykład poniżej znajduje się prosty kod łączący cztery łańcuchy.
Więc jeśli
str1
jestnull
to spróbowaćstr2
, jeślistr2
tonull
będzie starałstr3
i tak dalej, aż znajdzie ciąg o wartości innej niż NULL.Krótko mówiąc, operator koalescencyjny zwraca pierwszą wartość NON-NULL z łańcucha.
źródło
To krótka ręka dla operatora trójskładnikowego.
Lub dla tych, którzy nie robią trójki:
źródło
!= null
), jak i drugiformsAuth
(po?
) mogą być zmienione; w zerowej formie koalescencji obydwa domyślnie przyjmują podane wartości.Jeśli znasz Ruby,
||=
wydaje mi się , że jest podobny do C #??
. Oto niektóre Ruby:I w C #:
źródło
x ||= y
sprowadza się do czegoś podobnegox = x || y
, więc w??
rzeczywistości jest bardziej podobny do zwykłego||
w Ruby.??
tylko dba onull
, podczas gdy||
operator w Ruby, jak w większości języków, to bardziejnull
,false
lub coś, co można uznać za logiczną o wartościfalse
(na przykład w niektórych językach""
). To nie jest ani dobra ani zła rzecz, tylko różnica.operator koalescencyjny
jest to równoważne z
źródło
Nie ma w tym nic niebezpiecznego. W rzeczywistości jest piękny. Możesz dodać wartość domyślną, jeśli jest to pożądane, na przykład:
KOD
źródło
int? x1 = null;
Czy to prawdax1
-x4
MUSI być typami zerowalnymi: nie ma sensu mówić skutecznie: „wynikiem jest,0
jeślix4
jest wartością, której nie byłby w stanie przyjąć” (null
). „Typ dopuszczający wartości zerowe” obejmuje tutaj zarówno typy dopuszczające wartości zerowe, jak i typy referencyjne. Jest to błąd czasu kompilacji, jeśli jedna lub więcej zmiennych łańcuchowych (oprócz ostatniej) nie ma wartości zerowej.Jak słusznie wskazano w wielu odpowiedziach, że jest to „zerowy operator koalescencyjny” ( ?? ), mówiąc o którym możesz również chcieć sprawdzić jego kuzyna „zerowy operator warunkowy” ( ?. Lub ? [ ), Który jest operatorem, który wiele razy jest używany w połączeniu z ??
Operator nieważny
Na przykład:
stary sposób bez ? i ?? robienia tego jest
co jest bardziej pełne i kłopotliwe.
źródło
Tylko dla twojej rozrywki (wiedząc, że wszyscy jesteście facetami z C # ;-).
Myślę, że powstał w Smalltalk, gdzie istnieje od wielu lat. Jest tam zdefiniowany jako:
w obiekcie:
w UndefinedObject (aka nil's class):
Istnieją zarówno wersje oceniające (?), Jak i nieoceniające (??) tego.
Często można go znaleźć w metodach pobierających zmienne prywatne (instancja) zainicjowane z opóźnieniem, które są zerowe, dopóki nie są naprawdę potrzebne.
źródło
Niektóre przykłady uzyskiwania wartości przy użyciu koalescencji są nieefektywne.
Naprawdę chcesz:
lub
Zapobiega to odtwarzaniu obiektu za każdym razem. Zamiast zmiennej prywatnej pozostającej pustej i przy każdym żądaniu tworzony jest nowy obiekt, zapewnia to przypisanie zmiennej prywatnej, jeśli nowy obiekt zostanie utworzony.
źródło
??
skrót nie jest oceniany?new FormsAuthenticationWrapper();
jest oceniany wtedy i tylko wtedy, gdy_formsAuthWrapper
jest zerowy.Uwaga:
Przeczytałem cały ten wątek i wiele innych, ale nie mogę znaleźć tak dokładnej odpowiedzi, jak to jest.
Przez co całkowicie zrozumiałem „dlaczego używać? I kiedy używać? I jak korzystać?”.
Źródło:
Fundacja komunikacji Windows uwolniona przez Craiga McMurtry'ego ISBN 0-672-32948-4
Typy dopuszczające wartości zerowe
Istnieją dwie typowe okoliczności, w których chciałoby się dowiedzieć, czy wartość została przypisana do instancji typu wartości. Po pierwsze, instancja reprezentuje wartość w bazie danych. W takim przypadku chcielibyśmy mieć możliwość zbadania instancji w celu ustalenia, czy wartość rzeczywiście znajduje się w bazie danych. Inną okolicznością, bardziej związaną z przedmiotem tej książki, jest sytuacja, gdy instancja reprezentuje element danych otrzymany z jakiegoś zdalnego źródła. Ponownie chciałoby się ustalić z instancji, czy otrzymano wartość dla tego elementu danych.
.NET Framework 2.0 zawiera ogólną definicję typu, która zapewnia przypadki takie jak te, w których chce się przypisać wartość null do instancji typu wartości i przetestować, czy wartość instancji jest pusta. Ta ogólna definicja typu to System.Nullable, która ogranicza ogólne argumenty typu, które mogą być zastąpione T dla typów wartości. Instancjom typów zbudowanych z System.Nullable można przypisać wartość null; w rzeczywistości ich wartości są domyślnie zerowe. Zatem typy skonstruowane z System.Nullable można nazwać typami wartości zerowalnych. System.Nullable ma właściwość Value, dzięki której można przypisać wartość przypisaną do instancji typu zbudowanego na jej podstawie, jeśli wartość instancji nie jest równa null. Dlatego można napisać:
Język programowania C # zapewnia skróconą składnię do deklarowania typów zbudowanych z System.Nullable. Ta składnia pozwala na skrócenie:
do
Kompilator zapobiegnie próbie przypisania wartości typu wartości zerowej do zwykłego typu wartości w następujący sposób:
Uniemożliwia to zrobienie tego, ponieważ dopuszczalny typ wartości może mieć wartość null, co w rzeczywistości miałby w tym przypadku, a tej wartości nie można przypisać do zwykłego typu wartości. Chociaż kompilator zezwala na ten kod,
Druga instrukcja spowodowałaby zgłoszenie wyjątku, ponieważ każda próba dostępu do właściwości System.Nullable.Value jest niepoprawną operacją, jeśli typowi zbudowanemu z System.Nullable nie przypisano prawidłowej wartości T, co nie miało miejsca w tym przypadku walizka.
Wniosek:
Jednym z prawidłowych sposobów przypisania wartości typu zerowalnego wartości do zwykłego typu wartości jest użycie właściwości System.Nullable.HasValue w celu ustalenia, czy do typu wartości dopuszczalnej zerowej została przypisana poprawna wartość T:
Inną opcją jest użycie tej składni:
Przez co zwykła liczba całkowita myInteger jest przypisywana wartości zerowalnej liczby całkowitej „myNullableInteger”, jeśli ta ostatnia ma przypisaną prawidłową wartość całkowitą; w przeciwnym razie myInteger zostanie przypisana wartość -1.
źródło
Jest zerowym operatorem koalescencyjnym, który działa podobnie do operatora trójskładnikowego.
Innym interesującym punktem tego jest: „Typ zerowalny może zawierać wartość lub może być niezdefiniowany” . Jeśli więc spróbujesz przypisać typ wartości dopuszczającej wartości zerowe do typu wartości nie dopuszczającej wartości zerowej, otrzymasz błąd czasu kompilacji.
Więc zrobić to za pomocą? operator:
źródło
jest równa
Ale fajną rzeczą jest to, że możesz je połączyć, jak mówili inni ludzie. Jedyną nie poruszoną kwestią jest to, że można go użyć do zgłoszenia wyjątku.
źródło
??
Operatora nazywana jest operator null koalescencji. Zwraca operand po lewej stronie, jeśli operand nie jest pusty; w przeciwnym razie zwraca operand po prawej stronie.Ustaw
variable2
na wartośćvariable1
, jeślivariable1
NIE jest pusta; w przeciwnym razievariable1 == null
, ustawvariable2
na 100.źródło
Inni opisali
Null Coalescing Operator
całkiem dobrze. Dla zainteresowanych istnieje skrócona składnia, w której to (pytanie SO):FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
jest równoważne z tym:
FormsAuth ??= new FormsAuthenticationWrapper();
Niektórzy uważają to za bardziej czytelne i zwięzłe.
źródło