Полное руководство по языку программирования С# 14 и платформе .NET 10 / Классы, структуры и пространства имен

C# и .NET | Проверка на null, операторы ?. и ??

Начальный ⏱ 5 мин чтения 👁 2 🕓 обновлено 11.08.2026

Проверка на null. Null guard

Если мы собираемся использовать переменную или параметр, которые допускают значение null, то есть представляют nullable-тип (не важно значимый или ссылочный), то, чтобы избежать возникновения NullReferenceException, мы можем проверить на null:


void PrintUpper(string? text)
{
    if (text!=null)
    {
        Console.WriteLine(text.ToUpper());
    }    
}

В данном случае если параметр text не равен null, то вызываем у строки метод ToUpper(), который переводит символы строки в верхний регистр.

Кроме того, с помощью оператора is мы можем проверить значение объекта:

объект is значение

Если объект слева от оператора is имеет значение справа от оператора. тогда оператор is возвращает true, иначе возвращается false

Например, проверка параметра/переменной на значение null:


void PrintUpper(string? text)
{
    if (text is  null) return;
    Console.WriteLine(text.ToUpper());
}

Или, наоборот, с помощью is not можно проверить отсутствие значения:


void PrintUpper(string? text)
{
    if (text is not null) 
		Console.WriteLine(text.ToUpper());
}

Также можно проверить на соответствие типу, значение которого мы собираемся использовать:


void PrintUpper(string? text)
{
    if (text is string)
        Console.WriteLine(text.ToUpper());
    else 
        Console.WriteLine("NULL");
}

Подобные проверки еще называются null guard или условно говоря "защита от null".

Оператор ??

Оператор ?? называется оператором null-объединения. Он применяется для установки значений по умолчанию для типов, которые допускают значение null:

левый_операнд ?? правый_операнд

Оператор ?? возвращает левый операнд, если этот операнд не равен null. Иначе возвращается правый операнд. При этом левый операнд должен принимать null. Посмотрим на примере:


string? text = null;
string name = text ?? "Tom";  // равно Tom, так как text равен null
Console.WriteLine(name);	// Tom

int? id = 200;
int personid = id ?? 1; // равно 200, так как id не равен null
Console.WriteLine(personid);	// 200

Но мы не можем написать следующим образом:


int x = 44;
int y = x ?? 100;

Здесь переменная x представляет значимый тип int и не может принимать значение null, поэтому в качестве левого операнда в операции ?? она использоваться не может.

Также можно использовать производный оператора ??=


string? text = null;
text ??= "Sam";
// аналогично
// text = text ?? "Sam";
Console.WriteLine(text);    // Sam

int? id = 100;
id ??= 1;
// аналогично
//id = id ?? 1;
Console.WriteLine(id); // 100

Оператор условного null

Иногда при работе с объектами, которые принимают значение null, мы можем столкнуться с ошибкой: мы пытаемся обратиться к объекту, а этот объект равен null. Например, пусть у нас есть следующая система классов:


class Person
{
    public Company? Company { get; set; }   // место работы
}
class Company
{
    public string? WebSite { get; set; }    // веб-сайт компании
}

Объект Person представляет человека. Его свойство Company представляет компанию, где человек работает. Но человек может не работать, поэтому свойство Company имеет тип Company?, то есть может иметь значение null.

Класс Company в свою очередь содержит свойство WebSite, которое представляет веб-сайт компании. Но у компании может и не быть собственного веб-сайта. Поэтому это свойство имеет тип string?, то есть также допускает значение null.

Допустим, нам надо вывести на консоль заглавными буквами веб-сайт компании, где работает человек (если он, конечно, работает и если у компании, где он работает, есть сайт). На первый взгляд мы можем написать следующую конструкцию:


void PrintWebSite(Person? person)
{
    if (person != null)
    {
        if(person.Company != null)
        {
            if(person.Company.WebSite != null)
            {
                Console.WriteLine(person.Company.WebSite.ToUpper());
            }
        }
    }
}
class Person
{
    public Company? Company { get; set; }   // место работы
}
class Company
{
    public string? WebSite { get; set; }    // веб-сайт компании
}

В методе PrintWebSite() принимаем объект Person? и, чтобы избежать исключения NullReferenceException, последовательно проверяем все используемые значения на null, чтобы в конце с помощью метода ToUpper() вывести заглавными буквами название сайта.

Хоть это и рабочий способ, но для простого вывода строки получается многоэтажная конструкция, но на самом деле ее можно сократить:


void PrintWebSite(Person? person)
{
    if (person != null && person.Company != null && person.Company.WebSite != null)
    {
        Console.WriteLine(person.Company.WebSite.ToUpper());
    }
}

Конструкция намного проще, но все равно получается довольно большой. И чтобы ее упростить, в C# есть оператор условного null (Null-Conditional Operator) - оператор ?.:


объект?.компонент

Если объект не равен null, то происходит обращение к компоненту объекта - полю, свойству, методу. Если объект представляет значение null, обращение к компаненту метода не происходит.

Применим данный оператор, изменив предыдущий пример:


void PrintWebSite(Person? person)
{
    Console.WriteLine(person?.Company?.WebSite?.ToUpper());
}

Таким образом, если person не равен null, то происходит обращение к его свойству Company. Если свойство Company не равно null, то идет обрашение к свойству WebSite объекта Company. Если свойство WebSite не равно null, то идет обращение к методу ToUpper().

Присваивание с проверкой на null

Операторы доступа с проверкой на null - ?. и ?[] теперь можно использовать в левой части присваивания или составного присваивания. До C# 14 перед присваиванием свойству требовалось проверять переменную на null:


Person? person = null;

if(person is not null)
{
    person.Name = "Tom";
}

Console.WriteLine(person?.Name);   // ничего не выводит 

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

Начиная с C# 14 предыдущий код можно упростить с помощью оператора ?.:


Person? person = null;

// присваивание, если только person не равно null
person?.Name = "Tom";

Console.WriteLine(person?.Name);   // ничего не выводит 

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

В выражении person?.Name = "Tom" правая часть оператора присвоения = вычисляется только тогда, когда левая часть не равна null. Если переменная person равна null, присвоения не будет.

Причем та же логика присваивания с проверкой на null применяется и с составными операторами присваивания (+=, -= и другими). ​​Однако инкремент и декремент (++ и --) не допускаются.

Проверь себя

📋 Тест по теме «C# и .NET | Проверка на null, операторы ?. и ??» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

void _____(string? text)
{
    if (text!=null)
    {
        Console.WriteLine(text.ToUpper());
    }    
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

void PrintUpper(string? _____)
{
    if (text is  null) return;
    Console.WriteLine(text.ToUpper());
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

void PrintUpper(string? text)
{
    if (text is _____ null) 
		Console.WriteLine(text.ToUpper());
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

void PrintUpper(string? text)
{
    if (text is string)
        Console._____(text.ToUpper());
    else 
        Console.WriteLine("NULL");
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

void PrintUpper(string? text)
{
    if (text!=null)
    {
        _____.WriteLine(text.ToUpper());
    }    
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

    {
void PrintUpper(string? text)
    }
    if (text!=null)
{
        Console.WriteLine(text.ToUpper());
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «C# и .NET | Проверка на null, операторы ?. и ??»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «C# и .NET | Проверка на null, операторы ?. и ??», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

void PrintUpper(string? text)
{
    if (text!=null)
    {
        Console.WriteLine(text.ToUpper());
    }    
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «C# и .NET | Проверка на null, операторы ?. и ??»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

объект is значение
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «C# и .NET | Проверка на null, операторы ?. и ??»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «C# и .NET | Проверка на null, операторы ?. и ??»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «C# и .NET | Проверка на null, операторы ?. и ??». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.