Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Подсказка
Эта статья является частью раздела "Основы" для разработчиков , которые уже знают хотя бы один язык программирования и учат C#. Если вы не знакомы с программированием, сначала начните с учебных пособий по началу работы.
Исходя из Java или C++? C# обеспечивает безопасность null во время компиляции с помощью ссылочных типов, допускающих значение NULL. Цель аналогична аннотациям Java @NonNull, но их обеспечение осуществляется компилятором. C# также имеет выделенные операторы ?. и ??, которые делают null-безопасные выражения краткими.
null представляет отсутствие значения. При попытке получить доступ к члену в null ссылке путем вызова метода или чтения свойства среда выполнения выдает NullReferenceException.
// Accessing a member on null throws NullReferenceException at runtime:
// string? name = null;
// int length = name.Length; // throws NullReferenceException
// Check before you dereference:
string? name = null;
if (name is not null)
{
Console.WriteLine($"Name has {name.Length} characters.");
}
else
{
Console.WriteLine("Name has no value.");
}
// Output: Name has no value.
C# предоставляет три дополнительных средства для написания кода, безопасного со значением NULL:
- Типы значений допускающие значение null: позволяют типу значения, например
intилиbool, также хранитьnull. -
Ссылочные типы, допускающие значение NULL, позволяют компилятору отслеживать, может ли ссылка быть
null - Операторы NULL: безопасный для null доступ и логика запасного варианта
Типы значений, допускающие значение NULL
Такие типы значений, как int, doubleи bool не могут храниться null по умолчанию. Добавьте ? к имени типа, чтобы создать nullable тип данных, который может содержать либо значение, либо null:
int? score = null;
Console.WriteLine(score.HasValue); // False
score = 95;
Console.WriteLine(score.HasValue); // True
Console.WriteLine(score.GetValueOrDefault()); // 95
int? missing = null;
Console.WriteLine(missing.GetValueOrDefault(-1)); // -1
Типы значений, допускающие значение NULL, полезны, если базовый тип значения должен представлять "нет данных". Распространенные сценарии включают столбцы базы данных, которые могут быть отсутствуют, необязательные параметры конфигурации и данные датчиков, которые еще не записаны.
Полный охват объявления, проверки и преобразования см. в разделе "Типы значений, допускающих значение NULL".
Ссылочные типы, допускающие значение null
Ссылочные типы, такие как string массивы и экземпляры классов, могут содержать null во время выполнения.
Ссылочные типы, допускающие значение NULL — это функция компилятора, которая делает намерение null явным и выявляет ошибки во время компиляции.
Используя аннотацию ?, вы объявляете свое намерение:
-
string?— это возможноnullссылка; компилятор предупреждает, если вы разыменовываете её без предварительной проверки. -
string— эта ссылка не должна бытьnull; компилятор предупреждает, если ему присваиваютnull.
// string? means this reference might be null
// string means this reference should not be null
string? nullableName = null;
string nonNullName = "Alice";
// ?. safely accesses a member when the reference might be null
string display = nullableName?.ToUpper() ?? "(no name)";
Console.WriteLine(display); // (no name)
display = nonNullName.ToUpper(); // safe: nonNullName is never null
Console.WriteLine(display); // ALICE
Все проекты .NET, которые создают современные шаблоны SDK, по умолчанию включают ссылочные типы, допускающие значение NULL. Полные рекомендации по включению и аннотации см. в разделе "Ссылочные типы, допускающие значение NULL".
Операторы NULL
C# включает в себя несколько операторов, которые позволяют писать код, безопасный в случае null, без использования ручной проверки на null везде.
| Оператор | Name | Purpose |
|---|---|---|
?. |
Доступ к члену с условием NULL | Доступ к члену только в том случае, если объект не является NULL |
?[] |
Нулевой условный доступ к индексатору | Доступ к элементу только в том случае, если коллекция не является NULL |
?? |
Объединение с значением NULL | Возвращает резервное значение, если выражение имеет значение null |
??= |
Присваивание по объединяющему оператору NULL | Назначайте только в том случае, если переменная null |
is null / is not null |
Шаблон NULL | Предпочтительный тест на null |
string? city = GetCity();
// ?. — access a member only when non-null
int? len = city?.Length;
// ?? — substitute a default when null
string display = city ?? "unknown";
// is null — preferred null test
if (city is null)
{
Console.WriteLine("No city provided.");
}
else
{
Console.WriteLine($"{display} ({len} chars)");
}
// Output: No city provided.
Подробные примеры каждого оператора см. в разделе Null operators.
Типы значений с поддержкой NULL и ссылочные типы с поддержкой NULL служат различным целям
Типы значений, допускающие значение NULL, и ссылочные типы, допускающие значение NULL, не являются альтернативными. Они решают различные проблемы:
- Используйте
T?для типа значения, который должен представлять "нет значения". Например, используйтеint?для необязательного столбца базы данных или дляDateTime?события, которое еще не запланировано. - Используйте
string?и другие аннотации допускающие значение NULL, чтобы показать, что ссылка может бытьnull, чтобы компилятор мог предупреждать вас до того, как произойдетNullReferenceExceptionво время выполнения.
Вместе эти функции и операторы NULL дают полный набор инструментов для записи кода C#, безопасного со значением NULL.