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

Zobacz demo

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

Zobacz demo

Ł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

Zobacz demo

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 ) );


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow