Оператор проверки на null
Безопасный доступ с помощью ?..
«Оператор проверки на null» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Проблема цепочек со значением null
Обращение к члену объекта через ссылку со значением null вызывает исключение NullReferenceException. Это один из самых распространённых сбоев во время выполнения в C#.
Если Вы последовательно вызываете члены, например user.Address.City, любое звено цепочки может оказаться равным null, и раньше эту проблему решали башней из проверок if.
Знакомимся с ?.
Оператор условного доступа к члену ?. прекращает вычисление всего выражения. Если левая часть равна null, результатом будет null, а не исключение.
Его можно прочитать так: «получить доступ к этому члену, но только если объект не равен null».
string name = null;
int? length = name?.Length;
System.Console.WriteLine(length == null);Результат становится допускающим null
Поскольку ?. может вернуть null, тип результата становится допускающим null. Выражение name?.Length имеет тип int?, а не int.
Именно поэтому его следует сохранять в int?, а не в обычный int.
string text = "hello";
int? len = text?.Length;
System.Console.WriteLine(len);Рабочий пример
Эта программа показывает, что ?. возвращает значение, когда объект существует, и null, когда его нет.
Запустите её и обратите внимание: исключение ни разу не возникает.
using System;
class Program
{
static void Main()
{
string a = "world";
string b = null;
Console.WriteLine(a?.ToUpper());
Console.WriteLine(b?.ToUpper() ?? "(null)");
}
}Объединение нескольких операторов ?.
Можно использовать ?. для последовательного доступа к нескольким членам. Как только любая часть оказывается равной null, вся цепочка останавливается и возвращает null.
Поэтому выражение customer?.Order?.Total безопасно, даже если customer или Order равен null.
string s = null;
int? upperLen = s?.ToUpper()?.Length;
System.Console.WriteLine(upperLen == null);Индексатор с условным доступом ?[]
Для массивов и списков существует форма индексатора ?[]. Если коллекция равна null, обращение по индексу возвращает null, а не приводит к сбою.
Обратите внимание: этот оператор защищает от значения null у коллекции, но не от выхода индекса за допустимый диапазон.
int[] data = null;
int? first = data?[0];
System.Console.WriteLine(first == null);Безопасный вызов методов
Оператор ?. также защищает вызовы методов. list?.Clear() вызывает Clear, только если list не равен null; в противном случае ничего не происходит.
Для метода, возвращающего void, всё выражение при значении null просто не выполняет никаких действий.
System.Collections.Generic.List<int> list = null;
list?.Add(5);
System.Console.WriteLine("No crash");Потокобезопасный вызов события
Классический пример использования — вызов событий. SomeEvent?.Invoke(this, args) безопасно вызывает событие, только если на него подписан хотя бы один обработчик.
Этот подход заменил прежний шаблон с проверкой на null, поскольку между проверкой и вызовом могла возникнуть гонка.
System.Action handler = null;
handler?.Invoke();
System.Console.WriteLine("Invoked safely");Сочетание с ??
?. естественно сочетается с оператором объединения с null ??, который предоставляет запасное значение, если цепочка равна null.
name?.Length ?? 0 возвращает длину или 0, если name равен null.
string name = null;
int length = name?.Length ?? 0;
System.Console.WriteLine(length);Тонкий нюанс
Даже если итоговый тип значения не допускает null, использование ?. делает выражение допускающим null. Выражение list?.Count имеет тип int?, а не int.
Если Вам нужен обычный int, добавьте ?? 0 или используйте GetValueOrDefault().
var list = new System.Collections.Generic.List<int> { 1, 2 };
int count = list?.Count ?? 0;
System.Console.WriteLine(count);Полное сравнение
Эта программа сопоставляет многословный подход с if и лаконичный вариант с ?.. Оба предотвращают исключение, но ?. гораздо понятнее.
using System;
class Program
{
static void Main()
{
string s = null;
int len = s != null ? s.Length : -1;
Console.WriteLine(len);
Console.WriteLine(s?.Length ?? -1);
}
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли оператор условного доступа к члену.
Итоги
Оператор условного доступа к члену ?. (и индексатор ?[]) прекращает обращение к члену, если объект равен null, и возвращает null вместо возникновения исключения.
Результат становится допускающим null, поэтому сочетайте этот оператор с ??, чтобы предоставить запасное значение.
Часто задаваемые вопросы
Урок «Оператор проверки на null» бесплатный?
Да — полный текст урока «Оператор проверки на null» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Оператор проверки на null»?
Безопасный доступ с помощью ?.. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Оператор проверки на null»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Типы значений, допускающие null
- Оператор проверки на null
- Операторы объединения с null
- Защита от null