„Oceń pierwszy operand; jeśli jest to null, zatrzymaj z wynikiem null. W przeciwnym razie oceń drugi operand (jako dostęp członka pierwszego operandu).”
W twoim przykładzie chodzi o to, że jeśli ajest null, to zamiast a?.PropertyOfAoceny nullzgłasza wyjątek - porównuje to nullodwołanie z foo(przy użyciu ==przeciążenia łańcucha ), stwierdzi, że nie są one równe, a wykonanie przejdzie do treści ifinstrukcji .
Innymi słowy, wygląda to tak:
string bar =(a ==null?null: a.PropertyOfA);if(bar != foo){...}
... z wyjątkiem tego, że aocenia się tylko raz.
Pamiętaj, że może to również zmienić typ wyrażenia. Rozważmy na przykład FileInfo.Length. Jest to właściwość typu long, ale jeśli użyjesz jej z operatorem warunkowym o wartości NULL, otrzymasz wyrażenie typu long?:
FileInfo fi =...;// fi could be nulllong? length = fi?.Length;// If fi is null, length will be null
Czy to nie jest nazywane zerowym operatorem warunkowym ?
SLaks
1
@SLaks: Myślałem, że to „warunkowe zero”, ale mogę się mylić. Ostatnim razem, gdy sprawdzałem dokumenty dotyczące języka Roslyn, nie zmieniono jego nazwy na żadną z nich. Może źródłem jest tu władza - sprawdzi.
Jon Skeet,
3
@SLaks: Jasne. W SyntaxKind najwyraźniej jest to ConditionalAccessExpression, co irytująco nie jest żadnym z nich ...
Jon Skeet
12
Wolałem
3
Dla przypomnienia widziałem pięć różnych nazw tego operatora: bezpieczną nawigację, zerową-warunkową, zerową propagację, warunkowy dostęp, Elvis.
Gigi,
81
Może być bardzo przydatny podczas spłaszczania hierarchii i / lub mapowania obiektów. Zamiast:
Aby uratować ludzi patrząc na co? jest .. Jest operatorem zerowania koalescencji i zwraca nazwę, jeśli nie jest zerowa, w przeciwnym razie zwróci „nie dotyczy”.
Steve
6
@Erik Philips Chyba trzeba dodać || Model.Model2.Model3.Model4.Name == null mieć tę samą logikę, poza tym sprawa Model.Model2.Model3.Model4.Namejest null, mapped.Namepozostanienull
RazvanR
2
@ErikPhilips Chyba nie na tej samej stronie. Spróbuj, co się dzieje w obu przypadkach, jeśli tak Model.Model2.Model3.Model4.Namejest null.
@ErikPhilips: To nie ma nic wspólnego z pierwszym komentarzem, ponieważ nie odnosi się to do twojego pierwszego przykładu. W ten sposób wskoczyłbyś do elseoddziału i miałbyś mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null, podczas gdy drugi przykład zastąpiłby mapped.Name = "N/A". Zobacz edytowany DotNetFiddle
derM
3
Jest to stosunkowo nowe w C #, co ułatwia nam wywoływanie funkcji w odniesieniu do wartości zerowej lub innej w łańcuchu metod.
starym sposobem na osiągnięcie tego samego było:
var functionCaller =this.member;if(functionCaller!=null)
functionCaller.someFunction(var someParam);
Może być bardzo przydatny podczas spłaszczania hierarchii i / lub mapowania obiektów. Zamiast:
Można to napisać jak (taka sama logika jak powyżej)
Przykład działania DotNetFiddle.Net .
( operator koalescencyjny? lub null jest inny niż operator warunkowy? lub null ).
Może być również używany po stronie operatorów przypisania za pomocą Action. Zamiast
Można to uprościć:
Przykład DotNetFiddle :
using System;
Wynik:
źródło
|| Model.Model2.Model3.Model4.Name == null
mieć tę samą logikę, poza tym sprawaModel.Model2.Model3.Model4.Name
jestnull
,mapped.Name
pozostanienull
Model.Model2.Model3.Model4.Name
jestnull
.else
oddziału i miałbyśmapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
, podczas gdy drugi przykład zastąpiłbymapped.Name = "N/A"
. Zobacz edytowany DotNetFiddleJest to stosunkowo nowe w C #, co ułatwia nam wywoływanie funkcji w odniesieniu do wartości zerowej lub innej w łańcuchu metod.
starym sposobem na osiągnięcie tego samego było:
a teraz stało się to znacznie łatwiejsze dzięki:
Zdecydowanie polecam przeczytać tutaj:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
źródło