Как работают ссылочные типы C#, допускающие значение NULL?
Одной из основных особенностей C# 8.0 является концепция ссылочных типов, допускающих значение NULL, которая представляет собой серьезный сдвиг в том, как программисты могут работать с нулевыми данными. Мы обсудим, как они работают и как их использовать.
Что такое нулевые ссылочные типы?
В C# есть два основных типа переменных. Типы значений имеют фиксированные размеры, например int
, float
и bool
. Они передаются между функциями по значению и обычно хранятся в стеке — очень быстрой памяти, которая очищается при выходе за пределы области видимости. Они никогда не могут быть нулевыми, но с помощью структуры Nullable
типы значений можно сделать так, чтобы они поддерживали нулевые данные, если вы хотите такого поведения.
Другой тип — это ссылочные типы, которые представляют собой более крупные объекты без фиксированного размера, такие как строки и списки. Они почти всегда хранятся в куче, а переменная в стеке является ссылкой на ячейку памяти.
Проблема в том, что ссылочные типы могут стать нулевыми. Переменной, в которой хранится местоположение, может быть присвоено нулевое значение, что довольно часто встречается, особенно при работе с данными, наличие которых не гарантируется, например, с необязательными вопросами в веб-форме. Вот почему .NET нуждается в сборщике мусора для очистки объектов, на которые больше нет активных ссылок.
Если вы программист .NET, вы определенно привыкли к проверке на нуль, когда вы вручную проверяете, не стало ли что-то нулевым, прежде чем использовать его. Это хорошо работает, и это очень дешевая операция, но во многих случаях в ней нет необходимости. Чтобы ссылочный тип был нулевым, он либо не был инициализирован правильным значением, либо ему было присвоено вручную значение null
, например,
variable = null;
Обнуляемые ссылочные типы — это новое дополнение, которое, по сути, обеспечивает различие между ссылочными переменными, которые могут стать нулевыми, и ссылочными переменными, которые не могут. Это критическая функция, которая, скорее всего, оставит в вашей кодовой базе множество предупреждений, поэтому вам придется включать ее вручную. Как только он включен, компилятор начинает различать:
строка?
, которая может быть нулевой и сохраняет поведение «по умолчанию» из более ранних версий, истрока
, которая не может быть нулевой. Он никогда не может быть нулевым, потому что ему должно быть присвоено значение по умолчанию, и его нельзя установить равным нулю.
Если эта функция включена, ссылочные типы будут работать в основном так же, как и типы значений — никогда не станут нулевыми, если только вы не сообщите компилятору, что это возможно с помощью синтаксиса Type?
. Технически «ссылочные типы, допускающие значение NULL» — это то, что всегда было в C#, а новая функция — ссылочные типы, не допускающие значения NULL, которые заменяют старые.
Эта простая функция позволяет сообщить компилятору о ваших намерениях относительно переменной. Если вы попытаетесь присвоить значение string?
, допускающее значение NULL, переменной string
, не допускающей значение NULL, вы получите предупреждение о том, что вы неправильно обрабатываете null.
Чтобы исправить это предупреждение, вам нужно установить ненулевое значение только после проверки, не является ли оно нулевым. Компилятор умен и знает, когда и где значение может быть нулевым. Если вы поместите его в блок if (value != null)
, он не выдаст вам предупреждения и напомнит вам, что он не равен null при его использовании.
В отличие от типов значений, допускающих значение NULL, ссылочные типы, допускающие значение NULL, неявно преобразуются в их эквиваленты, не допускающие значение NULL, хотя и с предупреждением.
Вы можете использовать ссылочные типы, допускающие значение NULL, везде, где можно использовать обычные типы, будь то локальная переменная, поля или свойства для классов и структур, а также входные параметры для функций. Если вы попытаетесь преобразовать их в ненулевые значения без проверки, вы получите сообщение об ошибке.
Как включить обнуляемый контекст
В обозревателе решений щелкните проект правой кнопкой мыши и выберите «Редактировать файл проекта». Возможно, вам придется сначала выгрузить его, чтобы увидеть эту опцию.
<Nullable>enable</Nullable>
Если вы используете устаревший формат проекта, вам может потребоваться вручную переопределить это с помощью директивы в верхней части каждого файла:
#nullable enable
Если вы не хотите включать предупреждения, вы можете использовать контекст «Аннотации», который будет отображать аннотации только при наведении на них курсора.