При использовании новых функций явных ссылочных типов, допускающих значение NULL, в C# 8.0 (все типы должны быть явно объявлены как допускающие значение NULL, если они должны быть установлены в null https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references ), как вы справляетесь со следующей ситуацией:
Скажем, у вас есть функция, которая возвращает IEnumerable из Something?
var result = aFunction()
.Where(data => data != null)
.Select(data => data.Id).ToList();
data.Id отображается как ошибка (у меня есть предупреждения об ошибках):
потому что он может быть нулевым, даже если он проверяется, чтобы быть не нулевым с помощью Where. Я не хочу подавлять ошибку в этом случае, есть ли способ справиться с этим синтаксически?
ссылочные типы, допускающие значение NULL, не имеют HasValue
я не понимаю, почему это субъективно
Я не получаю предупреждений, и в моем тестовом проекте все выглядит нормально (Visual Studio 2022, .Net 6, консольный проект)
это будет потому, что у вас не включено «nullable». это относительно новая функция, см. здесь: docs.microsoft.com/en-us/dotnet/csharp/nullable-references. Также нужны предупреждения, как ошибки, чтобы создать ошибку. Это устраняет риск исключений с нулевыми ссылками.
Он у меня есть, и я очень хорошо об этом знаю. <Nullable>включить</Nullable>
Я думаю, что в этом конкретном случае вам нужно вручную сказать, что данные не равны нулю: Select(data => data!.Id)
Я не думаю, что компилятор это понимает\
Фраза «Как вы поступите в следующей ситуации» показалась мне субъективной, но, возможно, это спорно. Дайте мне секунду, чтобы просмотреть это утверждение об отсутствии HasValue
для явно обнуляемого ссылочного типа в отношении этой функции. Я могу что-то неправильно понять.
@Bizhan, который в основном подавляет предупреждение, но я думаю, что это ответ. Я не знал об этом! обозначение. Это синтаксически аккуратно.
Вы можете попробовать aList.Where(data => data != null).OfType<Something>().Select(data => data.Id).ToList();
попробуй var result = aList.Select(data => data?.Id).Where(id=>id.HasValue).ToList();
Это работает для меня... dotnetfiddle.net/ofj2AQ
я обновил ответ, я упростил его из своего кода
правильно, поэтому ссылка, допускающая значение NULL, отличается от того, что я понял.
примечание: data != null
на самом деле не означает, что data
не null
; вы можете создать тип, который действительно выдаст NRE в этом случае (т. е. data
все еще может быть null
); чтобы проверить «данные не являются нулевыми», не спрашивая «что это за тип? как он себя ведет?» вам действительно следует использовать тест data is not null
(по крайней мере, в последних версиях C#; вы можете сделать то же самое в более старых версиях C#, но он более подробный)
пример: Sharlab.io/…
Компилятор недостаточно «умен», чтобы определить, что аргумент Select()
не может быть нулевым в этом случае, поскольку он выполняет только статический анализ кода. Для таких ситуаций ! нотация была введена с нулевыми ссылочными типами. Применение восклицательного знака к объекту говорит компилятору «заткнуться» в отношении предупреждений о допустимости значений NULL.
var result = aFunction()
.Where(data => data != null)
.Select(data => data!.Id).ToList();
Это означает, что компилятор не будет генерировать предупреждение о том, что data
может быть нулевым. Это полезно во всех случаях, когда вы знаете, что значение не равно null, но компилятор (например, из-за сложности кода) не определяет это должным образом.
Обратите внимание, что это действительно удаляет только предупреждение. Если значение на самом деле равно нулю, код будет вести себя так же, как и раньше, поэтому он выдаст NullReferenceException
.
спасибо за ответ, я, вероятно, воспользуюсь этим, однако для абсолютной уверенности в том, что не будут получены исключения нулевых ссылок, использование OfType<Something> в приведенном выше примере, по-видимому, работает во всех случаях без исключений нулевых ссылок.
Да, но это также добавляет сложности. Мой ответ указывает на общее использование восклицательного знака, поскольку он также может быть полезен вне запросов linq (например, с полями, допускающими значение NULL, которые, как вы знаете, не являются нулевыми в каком-либо методе).
с этим фрагментом.. Я не думаю, что вы получите нулевую ссылку, Тим. Решение здесь заключается в устранении предупреждения статического анализа компилятора. Это предупреждение является ошибкой, потому что вы рассматриваете предупреждения как ошибки. и да, введение сложностей — с OfType
— кажется необоснованным.
кроме того, nullable-reference-types для языковой функции немного более актуален / ограничен для этого обсуждения (тогда ссылка в вопросе). docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
вы задаете субъективный вопрос здесь. Что вы пробовали? Вы пробовали
data.HasValue
в предложении where иdata.Value.Id
в Select/Projection/Map?