Поиск…


Синтаксис

  • ? X .Y; // null, если X имеет значение null else XY
  • ? X .Y .Z; // null, если X является нулевым, или Y имеет значение null else XYZ
  • ? Х [индекс]; // null, если X имеет значение null else X [index]
  • ? Х .ValueMethod (); // null, если X является null else результатом X.ValueMethod ();
  • ? Х .VoidMethod (); // ничего не делать, если X является null else, вызывать X.VoidMethod ();

замечания

Обратите внимание, что при использовании оператора нулевой коалесценции на типе значений T вы получите Nullable<T> назад.

Null-Conditional Operator

?. оператор - синтаксический сахар, чтобы избежать подробных нулевых проверок. Он также известен как безопасный навигатор .


Класс, используемый в следующем примере:

public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
    public Person Spouse { get; set; }
}

Если объект является потенциально нулевым (например, функция, возвращающая ссылочный тип), сначала объект должен быть проверен на значение null, чтобы предотвратить возможное исключение NullReferenceException . Без оператора с нулевым условием это выглядело бы так:

Person person = GetPerson();

int? age = null;
if (person != null)
    age = person.Age;

В этом же примере используется оператор с нулевым условием:

Person person = GetPerson();

var age = person?.Age;    // 'age' will be of type 'int?', even if 'person' is not null

Цепочка оператора

Оператор с нулевым условием может быть объединен с элементами и под-членами объекта.

// Will be null if either `person` or `person.Spouse` are null
int? spouseAge = person?.Spouse?.Age;

Объединение с оператором Null-Coalescing

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

// spouseDisplayName will be "N/A" if person, Spouse, or Name is null
var spouseDisplayName = person?.Spouse?.Name ?? "N/A";

Условный индекс

Аналогично « ?. оператор, оператор индекса с нулевым условием проверяет нулевые значения при индексировании в коллекцию, которая может быть нулевой.

string item = collection?[index];

синтаксический сахар для

string item = null;
if(collection != null)
{
    item = collection[index];
}

Избегание NullReferenceExceptions

var person = new Person
{
    Address = null;
};

var city = person.Address.City; //throws a NullReferenceException
var nullableCity = person.Address?.City; //returns the value of null

Этот эффект можно связать вместе:

var person = new Person
{
    Address = new Address
    {
        State = new State
        {
            Country = null
        }
    }
};

// this will always return a value of at least "null" to be stored instead
// of throwing a NullReferenceException
var countryName = person?.Address?.State?.Country?.Name; 

Оператор Null-условный может использоваться с методом расширения

Метод расширения может работать с нулевыми ссылками , но вы можете использовать ?. для того, чтобы все равно проверить нуль.

public class Person 
{
    public string Name {get; set;}
}

public static class PersonExtensions
{
    public static int GetNameLength(this Person person)
    {
        return person == null ? -1 : person.Name.Length;
    }
}

Обычно метод запускается для null ссылок и возвращает -1:

Person person = null;
int nameLength = person.GetNameLength(); // returns -1

Использование ?. метод не будет запущен для null ссылок, а тип - int? :

Person person = null;
int? nameLength = person?.GetNameLength(); // nameLength is null.

Такое поведение действительно ожидается от того, как ?. оператор работает: он избегает вызова экземпляров экземпляра для нулевых экземпляров, чтобы избежать NullReferenceExceptions . Однако эта же логика применяется к методу расширения, несмотря на разницу в том, как объявлен метод.

Для получения дополнительной информации о том, почему метод расширения вызывается в первом примере, см. Методы расширения - нулевая проверка документации.



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