// #nullable enable annotations
TestClass? badDefinition = null;
// Предупреждение CS8632 The annotation for nullable reference types
// should only be used in code within a '#nullable' annotations
// Заметка для ссылочных типов, допускающих значение null,
// должна использоваться только в коде внутри
#nullable enable annotations
string? anotherNullableString = null;
#nullable restore
В заключение важно отметить, что ссылочные типы, допускающие значение null
, не имеют свойств HasValue
и Value
, т.к. они предоставляются System.Nullable
.
Рекомендации по переносу кода
Если при переносе кода из C# 7 в C# 8 или C# 9 вы хотите задействовать ссылочные типы, допускающие значение null
, то можете использовать для работы с кодом комбинацию настройки проекта и директив компилятора. Общепринятая практика предусматривает первоначальное включение предупреждений и отключение заметок о допустимости значения null
для всего проекта. Затем по мере приведения в порядок областей кода применяйте директивы компилятора для постепенного включения заметок.
Работа с типами, допускающими значение null
Для работы с типами, допускающими значение null
, в языке C# предлагается несколько операций. В последующих разделах рассматриваются операция объединения с null
, операция присваивания с объединением с null
и null
-условная операция. Для проработки примеров используйте ранее созданный проект FunWithNullableValueTypes
.
Операция объединения с null
Следующий важный аспект связан с тем, что любая переменная, которая может иметь значение null (т.е. переменная ссылочного типа или переменная типа, допускающего null
), может использоваться с операцией ??
языка С#, формально называемой null
. Операция ??
позволяет присваивать значение типу, допускающему null
, если извлеченное значение на самом деле равно null
. В рассматриваемом примере мы предположим, что в случае возвращения методом GetlntFromDatabase()
значения null
(конечно, данный метод запрограммирован так, что он null
, но общую идею вы должны уловить) локальной переменной целочисленного типа, допускающего null
, необходимо присвоить значение 100
. Возвратитесь к проекту NullableValueTypes
(сделайте его стартовым) и введите следующий код:
// Для краткости код не показан
Console.WriteLine("***** Fun with Nullable Data *****\n");
DatabaseReader dr = new DatabaseReader();
// Если значение, возвращаемое из GetlntFromDatabase(), равно
// null, тогда присвоить локальной переменной значение 100.
int myData = dr.GetIntFromDatabase() ?? 100;
Console.WriteLine("Value of myData: {0}", myData);
Console.ReadLine();
Преимущество применения операции ??
заключается в том, что она дает более компактную версию кода, чем традиционный условный оператор if/else
. Однако при желании можно было бы написать показанный ниже функционально эквивалентный код, который в случае возвращения null
обеспечит установку переменной в значение 100:
// Более длинный код, в котором не используется синтаксис ??.
int? moreData = dr.GetIntFromDatabase();
if (!moreData.HasValue)
{
moreData = 100;
}
Console.WriteLine("Value of moreData: {0}", moreData);
// Вывод значения moreData
Операция присваивания с объединением с null (нововведение в версии 8.0)
В версии C# 8 появилась null
(??=
), основанная на операции объединения с null
. Эта операция выполняет присваивание левого операнда правому операнду, только если левый операнд равен null
. В качестве примера введите такой код:
// Операция присваивания с объединением с null
int? nullableInt = null;
nullableInt ??= 12;