Почему все еще можно присвоить null ссылочному типу, не допускающему значения NULL? - PullRequest
0 голосов
/ 06 мая 2020

Я запуталась. Я думал, что включение c# 8 и ссылочных типов, допускающих значение NULL, предотвратит присвоение значения NULL ссылочным типам, не допускающим значения NULL, но, по-видимому, это всего лишь предупреждение во время компиляции, я знаю, что вы можете заставить это быть ошибкой и остановить сборку, но я думал, что это больше, чем просто проверка компилятора.

Посмотрите на этот пример https://dotnetfiddle.net/4eCs5L

Если вы запустите, все еще можно присвоить null не ссылочный тип, допускающий значение NULL, почему это не вызывает ошибку во время выполнения?

Ответы [ 3 ]

2 голосов
/ 11 мая 2020

TL; DR: обратная совместимость

Если ссылочные типы, допускающие значение NULL, были бы частью C# 1, то присвоение null типу, не допускающему значение NULL, привело бы к ошибке компиляции.

Проблема C# в том, что уже существует много существующего кода без ссылочных типов, допускающих значение NULL. Ошибки компилятора при назначении null могут нарушить весь существующий код или библиотеки.

Вы можете найти полное объяснение в. NET сообщении в блоге от C# Program Manager: https://devblogs.microsoft.com/dotnet/nullable-reference-types-in-csharp/

0 голосов
/ 03 июля 2020

Цель этой функции - предоставить разработчикам больше инструментов для выявления наиболее распространенных типов ошибок, разграничения нулевой ссылки / указателя и, таким образом, сбоя приложения.

Таким образом, C# Команда разработчиков добавила «ссылочные типы, допускающие значение NULL», с синтаксисом, достаточным для того, чтобы разработчик мог более четко декларировать намерение и требования кода.

Вещи, которые могут быть выражены с помощью нового синтаксиса: * Свойства и поля, которые либо разрешают NULL, либо не допускают NULL

Параметры метода, которые могут быть NULL или должны быть NULL Возвращаемые значения метода могут быть NULL или не могут быть NULL

При включении компилятор будет использовать этот новый синтаксис, а также атрибуты и другие метаданные, чтобы начать выдавать предупреждения, когда он видит код, правильность которого не "гарантированно". Другими словами, если вы прочитаете свойство, в котором говорится, что оно может возвращать NULL, и попытаетесь просто передать это как значение параметра, когда метод говорит, что параметр не должен быть NULL, вы получите предупреждение.

Вы можете, используя существующие директивы в проектах, сказать, что определенные предупреждения должны вместо этого обрабатываться как ошибки, и прервать сборку, включая эти новые предупреждения.

ОДНАКО, они не добавили время выполнения чеки. Если вы говорите, что значение параметра никогда не должно быть NULL, и проигнорируете предупреждение или обойдете его (есть способы сказать «поверьте мне, это правильно»), то метод будет работать, как указано. Не существует невидимых операторов if или защитных операторов, которые проверяют, что параметр не равен нулю.

В принципе, вам все равно следует добавлять такие операторы if.

Это противоречит вашему мнению, именно для этого они разработали эту функцию. Они не забыли добавить эти проверки времени выполнения, они специально не добавляли их.

Например, если вы вызываете метод через отражение, компилятор не участвует, поскольку это вещь времени выполнения, и поэтому нет проверки будут проводиться у всех. Если метод не имеет таких защитных инструкций, вероятно, он будет sh позже взломать исключение NullReferenceException.

0 голосов
/ 06 мая 2020

Используя эту ссылку https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references

Я вижу, что директива #nullable enable: Sets the nullable annotation context and nullable warning context to enabled

Если вы все еще ожидаете, что она выдаст ошибку, добавьте это в свой файл проекта <WarningsAsErrors>nullable</WarningsAsErrors>

Compiler warnings for null assignments

...