Поиск…


Синтаксис

  • var result = possibleNullObject ?? значение по умолчанию;

параметры

параметр подробности
possibleNullObject Значение для проверки нулевого значения. Если значение не равно null, это значение возвращается. Должен быть тип с нулевым значением.
defaultValue Значение, возвращаемое, если possibleNullObject имеет значение NULL. Должен быть того же типа, что и possibleNullObject .

замечания

Нулевой оператор коалесцирования сам по себе является двумя последовательными символами вопросительного знака: ??

Это сокращение условного выражения:

possibleNullObject != null ? possibleNullObject : defaultValue

Левый операнд (тестируемый объект) должен быть типом типа NULL или ссылочным типом, или произойдет ошибка компиляции.

The ?? оператор работает как для ссылочных типов, так и для типов значений.

Основное использование

Используя null-coalescing operator (??) вы можете указать значение по умолчанию для типа NULL, если левый операнд имеет значение null .

string testString = null;
Console.WriteLine("The specified string is - " + (testString ?? "not provided"));

Живая демонстрация на .NET скрипке

Это логически эквивалентно:

string testString = null;
if (testString == null)
{
    Console.WriteLine("The specified string is - not provided");
}
else
{
    Console.WriteLine("The specified string is - " + testString);
}

или используя оператор тернарного оператора (? :) :

string testString = null;
Console.WriteLine("The specified string is - " + (testString == null ? "not provided" : testString));

Null fall-through and chaining

Левый операнд должен быть нулевым, в то время как правый операнд может быть или не быть. Результат будет набран соответствующим образом.

Ненулевые

int? a = null;
int b = 3;
var output = a ?? b;
var type = output.GetType();  

Console.WriteLine($"Output Type :{type}");
Console.WriteLine($"Output value :{output}");

Выход:

Тип: System.Int32
значение: 3

Посмотреть демо

Nullable

int? a = null;
int? b = null;
var output = a ?? b;

output будет иметь тип int? и равна b или null .

Многократное объединение

Коалесцирование также может выполняться в цепях:

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

Выход:

Тип: System.Int32
значение: 3

Посмотреть демо

Null Conditional Chaining

Оператор нулевого коалесцирования может использоваться в тандеме с оператором распространения пустоты для обеспечения более безопасного доступа к свойствам объектов.

object o = null;
var output = o?.ToString() ?? "Default Value";

Выход:

Тип: System.String
Значение: Значение по умолчанию

Посмотреть демо

Оператор коллаборации с вызовом метода

Оператор null coalescing позволяет легко убедиться, что метод, который может вернуть значение null , вернется к значению по умолчанию.

Без оператора нулевой коалесценции:

string name = GetName();

if (name == null)
    name = "Unknown!";

С нулевым коалесцирующим оператором:

string name = GetName() ?? "Unknown!";

Использовать существующие или создавать новые

Обычный сценарий использования, с которым эта функция действительно помогает, - это когда вы ищете объект в коллекции и вам нужно создать новый, если он еще не существует.

IEnumerable<MyClass> myList = GetMyList();
var item = myList.SingleOrDefault(x => x.Id == 2) ?? new MyClass { Id = 2 };

Инициализация ленивых свойств с помощью оператора нулевой коалесценции

private List<FooBar> _fooBars;

public List<FooBar> FooBars
{
    get { return _fooBars ?? (_fooBars = new List<FooBar>()); }
}

Первый раз , когда недвижимость .FooBars осуществляется доступ к _fooBars переменному будет оценивать , как null , таким образом , падает через к правопреемникам оператора присваивания и оценивает к полученному значению.

Безопасность резьбы

Это не потокобезопасный способ реализации ленивых свойств. Для поточнобезопасной лени используйте класс Lazy<T> встроенный в .NET Framework.

C # 6 Синтаксический сахар с использованием тел экспрессии

Обратите внимание, что с C # 6 этот синтаксис можно упростить с помощью тела выражения для свойства:

private List<FooBar> _fooBars;

public List<FooBar> FooBars => _fooBars ?? ( _fooBars = new List<FooBar>() );

Последующий доступ к свойству даст значение, хранящееся в переменной _fooBars .

Пример в шаблоне MVVM

Это часто используется при реализации команд в шаблоне MVVM. Вместо того, чтобы инициализировать команды с помощью конструкции модели, команды инициализируются лениво, используя этот шаблон следующим образом:

private ICommand _actionCommand = null;
public ICommand ActionCommand =>
   _actionCommand ?? ( _actionCommand = new DelegateCommand( DoAction ) );


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow