Для указания способности иметь значение
null
в ссылочных типах, допускающих
null
, применяется тот же самый символ
?
. Однако он не является сокращением для использования
System.Nullable<T>
, т.к. на месте
Т
могут находиться только типы значений. Не забывайте, что обобщения и ограничения рассматриваются в главе 10.
Включение ссылочных типов, допускающих null
Поддержка для ссылочных типов, допускающих
null
, управляется установкой контекста допустимости значения
null
. Это может распространяться на целый проект (за счет обновления файла проекта) или охватывать лишь несколько строк (путем применения директив компилятора). Вдобавок можно устанавливать следующие два контекста.
• Контекст с заметками о допустимости значения
null:
включает/отключает заметки о допустимости
null(?)
для ссылочных типов, допускающих
null
.
• Контекст с предупреждениями о допустимости значения
null:
включает/отключает предупреждения компилятора для ссылочных типов, допускающих
null
.
Чтобы увидеть их в действии, создайте новый проект консольного приложения по имени
FunWithNullableReferenceTypes
. Откройте файл проекта (если вы используете Visual Studio, тогда дважды щелкните на имени проекта в окне
Solution Explorer или щелкните правой кнопкой мыши на имени проекта и выберите в контекстном меню пункт
Edit Project file (Редактировать файл проекта)). Модифицируйте содержимое файла проекта для поддержки ссылочных типов, допускающих
null
, за счет добавления элемента
<Nullable>
(все доступные варианты представлены в табл. 4.5).
<Project Sdk="Microsoft .NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<b><Nullable>enable</Nullable></b>
</PropertyGroup>
</Project>
Элемент
<Nullable>
оказывает влияние на весь проект. Для управления меньшими частями проекта используйте директиву компилятора
#nullable
, значения которой описаны в табл. 4.6.
Ссылочные типы, допускающие null, в действии
Во многом из-за важности изменения ошибки с типами, допускающими значение
null
, возникают только при их ненадлежащем применении. Добавьте в файл
Program.cs
следующий класс:
public class TestClass
{
public string Name { get; set; }
public int Age { get; set; }
}
Как видите, это просто нормальный класс. Возможность принятия значения
null
появляется при использовании данного класса в коде. Взгляните на показанные ниже объявления:
string? nullableString = null;
TestClass? myNullableClass = null;
Настройка в файле проекта помещает весь проект в контекст допустимости значения
null
, который разрешает применение объявлений типов
string
и
TestClass
с заметками о допустимости значения
null
(
?
). Следующая строка кода вызывает генерацию предупреждения (CS8600) из-за присваивания
null
типу, не допускающему значение
null
, в контексте допустимости значения
null
:
// Предупреждение CS8600 Converting null literal or possible null
// value to non-nullable type
// Преобразование литерала null или возможного значения null
// в тип, не допускающий null
TestClass myNonNullableClass = myNullableClass;
Для более точного управления тем, где в проекте находятся контексты допустимости значения
null
, с помощью директивы компилятора
#nullable
можно включать или отключать контекст (как обсуждалось ранее). В приведенном далее коде контекст допустимости значения
null
(установленный на уровне проекта) сначала отключается, после чего снова включается за счет восстановления настройки из файла проекта:
#nullable disable
TestClass anotherNullableClass = null;
// Предупреждение CS8632 The annotation for nullable reference types
// should only be used in code within a '#nullable' annotations
// Заметка для ссылочных типов, допускающих значение null,
// должна использоваться только в коде внутри
// #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<T>
.