C# Language
Operator zerowo-koalescencyjny
Szukaj…
Składnia
- wynik var = możliwyNullObject ?? domyślna wartość;
Parametry
Parametr | Detale |
---|---|
possibleNullObject | Wartość do przetestowania pod kątem wartości zerowej. Jeśli nie jest pusta, zwracana jest ta wartość. Musi być typu zerowalnego. |
defaultValue | Wartość zwracana, jeśli to possibleNullObject NullObject ma wartość NULL. Musi być tego samego typu, jak possibleNullObject . |
Uwagi
Sam operator koalescencji zerowej to dwa kolejne znaki zapytania: ??
Jest to skrót od wyrażenia warunkowego:
possibleNullObject != null ? possibleNullObject : defaultValue
Operand po lewej stronie (testowany obiekt) musi być zerowym typem wartości lub typem odniesienia, w przeciwnym razie wystąpi błąd kompilacji.
?? operator działa zarówno dla typów referencyjnych, jak i typów wartości.
Podstawowe użycie
Użycie null-coalescing operator (??)
pozwala określić wartość domyślną dla typu zerowalnego, jeśli lewostronny operand jest null
.
string testString = null;
Console.WriteLine("The specified string is - " + (testString ?? "not provided"));
Wersja demonstracyjna na żywo .NET Fiddle
Jest to logicznie równoważne z:
string testString = null;
if (testString == null)
{
Console.WriteLine("The specified string is - not provided");
}
else
{
Console.WriteLine("The specified string is - " + testString);
}
lub za pomocą operatora trójskładnikowego (? :) :
string testString = null;
Console.WriteLine("The specified string is - " + (testString == null ? "not provided" : testString));
Brak spadania i wiązania
Operand po lewej musi być zerowalny, podczas gdy operand po prawej może, ale nie musi. Wynik zostanie odpowiednio wpisany.
Nie dopuszcza się zerowania
int? a = null;
int b = 3;
var output = a ?? b;
var type = output.GetType();
Console.WriteLine($"Output Type :{type}");
Console.WriteLine($"Output value :{output}");
Wynik:
Wpisz: System.Int32
wartość: 3
Nullable
int? a = null;
int? b = null;
var output = a ?? b;
output
będzie typu int?
i równe b
lub null
.
Wielokrotne łączenie
Koalescencję można również wykonać w łańcuchach:
int? a = null;
int? b = null;
int c = 3;
var output = a ?? b ?? c;
var type = output.GetType();
Console.WriteLine($"Type :{type}");
Console.WriteLine($"value :{output}");
Wynik:
Wpisz: System.Int32
wartość: 3
Łańcuch warunkowy zerowy
Operator koalescencji zerowej może być używany w parze z operatorem zerowania propagacji, aby zapewnić bezpieczniejszy dostęp do właściwości obiektów.
object o = null;
var output = o?.ToString() ?? "Default Value";
Wynik:
Wpisz: System.String
wartość: wartość domyślna
Operator koalescencji zerowej z wywołaniami metod
Operator koalescencji zerowej ułatwia upewnienie się, że metoda, która może zwrócić null
, spadnie do wartości domyślnej.
Bez zerowego operatora koalescencyjnego:
string name = GetName();
if (name == null)
name = "Unknown!";
Z zerowym operatorem koalescencji:
string name = GetName() ?? "Unknown!";
Użyj istniejącego lub utwórz nowy
Typowym scenariuszem użytkowania, w którym ta funkcja naprawdę pomaga, jest szukanie obiektu w kolekcji i konieczność utworzenia nowego, jeśli jeszcze nie istnieje.
IEnumerable<MyClass> myList = GetMyList();
var item = myList.SingleOrDefault(x => x.Id == 2) ?? new MyClass { Id = 2 };
Leniwa inicjalizacja właściwości z zerowym operatorem koalescencji
private List<FooBar> _fooBars;
public List<FooBar> FooBars
{
get { return _fooBars ?? (_fooBars = new List<FooBar>()); }
}
Przy pierwszym .FooBars
do właściwości _fooBars
zmienna _fooBars
będzie oceniana jako null
, przechodząc w ten sposób do instrukcji przypisania i przypisując wynikową wartość.
Bezpieczeństwo wątków
To nie jest bezpieczny dla wątków sposób implementowania leniwych właściwości. Aby lenistwo było bezpieczne dla wątków, użyj klasy Lazy<T>
wbudowanej w .NET Framework.
C # 6 Cukier syntaktyczny przy użyciu ciał ekspresyjnych
Zauważ, że od C # 6 tę składnię można uprościć, używając treści wyrażenia dla właściwości:
private List<FooBar> _fooBars;
public List<FooBar> FooBars => _fooBars ?? ( _fooBars = new List<FooBar>() );
Kolejny dostęp do właściwości da wartość przechowywaną w zmiennej _fooBars
.
Przykład we wzorze MVVM
Jest to często używane przy wdrażaniu poleceń we wzorze MVVM. Zamiast chętnie inicjować polecenia za pomocą konstrukcji viewmodela, polecenia są leniwie inicjowane przy użyciu tego wzorca w następujący sposób:
private ICommand _actionCommand = null;
public ICommand ActionCommand =>
_actionCommand ?? ( _actionCommand = new DelegateCommand( DoAction ) );