Skip to content

Посты

C# 8 - Nullable Reference Types

4 ноября 2019 г. • 3 мин чтения

C# 8 - Nullable Reference Types

Microsoft добавляет новую функцию в C# 8 под названием Nullable Reference Types. Что поначалу сбивает с толку, поскольку все ссылочные типы являются nullable… так чем это отличается? В дальнейшем, если функция включена, ссылочные типы являются non-nullable, если только вы явно не обозначите их как nullable.

Позвольте мне объяснить.

Nullable Reference Types

Когда Nullable Reference Types включены и компилятор считает, что ссылочный тип может быть null, он предупреждает вас. Вы увидите предупреждающие сообщения от Visual Studio:

И предупреждения сборки:

Чтобы убрать это предупреждение, добавьте знак вопроса в конце ссылочного типа. Например:

public string StringTest()
{
    string? notNull = null;
    return notNull;
}

Теперь ссылочный тип ведет себя так же, как до C# 8.

Эта функция включается добавлением <span class="inline-code"> #nullable enable </span> в начало любого файла C# или добавлением <span class="inline-code">lt;NullableReferenceTypes&gt;true&lt;/NullableReferenceTypes&gt;</span> в файл .csproj. По умолчанию она не включена, что хорошо, поскольку если бы она была включена, любая существующая кодовая база, вероятно, засветилась бы как рождественская елка.

Дебаты о Null

Почему Microsoft добавляет эту функцию сейчас? Null’ы были частью языка с самого, ну, начала? Честно говоря, я не знаю почему. Я всегда использовал null’ы, это факт жизни в C#. Я не понимал, что отсутствие null’ов было вариантом… Возможно, жизнь будет лучше без них. Мы узнаем.

Следует ли использовать null’ы или нет? Я обобщил продолжающиеся дебаты, как я их понимаю.

За

Аргумент в пользу null’ов обычно заключается в том, что объект имеет неизвестное состояние. Это неизвестное состояние представлено null’ом. Вы видите это с типом данных bit в SQL Server, который имеет 3 значения: null (не установлено), 0 и 1. Вы также видите это в пользовательских интерфейсах, где иногда важно знать, касался ли пользователь поля или нет. Кто-то может возразить: “Вместо null, почему бы не создать тип неизвестного состояния или состояние ‘не установлено’?” Чем это отличается от null? Вам все равно пришлось бы проверять это дополнительное состояние. Теперь вы создаете неизвестные состояния для каждого экземпляра. Почему бы просто не использовать null и иметь глобальное неизвестное состояние?

Против

Аргумент против null’ов заключается в том, что это другой тип данных, и его нужно проверять каждый раз при использовании ссылочного типа. В результате получается код вроде этого:

var user = GetUser(username, password);

if(user != null)
{
    DoSomethingWithUser(user);
} else 
{
    SetUserNotFoundErrorMessage()
}

Если метод GetUser возвращал бы пользователя во всех случаях, включая случаи, когда пользователь не найден. Если код никогда не возвращает null, то защита от него является пустой тратой времени и, в идеале, это упрощает код. Однако в какой-то момент вам нужно будет проверить пустого пользователя и отобразить сообщение об ошибке. Неиспользование null не устраняет необходимость обработки бизнес-случая “пользователь не найден”.

Является ли эта функция хорошей идеей?

Цель этой функции НЕ в том, чтобы исключить использование null’ов, а в том, чтобы задать вопрос: “Есть ли лучший способ?” И иногда ответ “Нет”. Если мы можем исключить постоянную проверку на null’ы с небольшой предусмотрительностью, что в свою очередь упрощает наш код. Я за. Хорошая новость в том, что C# сделал работу с null’ами тривиальной.

Я опасаюсь, что некоторые займут догматическую позицию и будут настаивать на исключении null’ов в ущерб системе. Это безнадежное дело, потому что null’ы являются неотъемлемой частью C#.

Являются ли Nullable Reference Types хорошей идеей? Да, если конечным результатом является более простой и менее подверженный ошибкам код.

Автор: Чак Конвей специализируется на разработке программного обеспечения и генеративном ИИ. Свяжитесь с ним в социальных сетях: X (@chuckconway) или посетите его на YouTube.

↑ Наверх

Вам также может понравиться