可空类型产生警告,因为项目已启用可空引用类型
Posted
技术标签:
【中文标题】可空类型产生警告,因为项目已启用可空引用类型【英文标题】:Nullable type producing warnings since project has enabled nullable reference types 【发布时间】:2022-01-08 05:35:43 【问题描述】:我只有在启用可空引用类型后才会收到警告,但具体示例实际上是旧的 Nullable<T>
类型:
var nullableItems = new List<int?>();
var actualNonNullValues = nullableItems.Where(x => x.HasValue)
.Select(x => x.Value)
.ToList();
所以我整理了所有的空值,只想要实际的非空项。但是,.Select(x => x.Value)
部分会给我一个关于x
可能在这里为空的编译器警告。逻辑上不是,但是对于编译器来说,类型还没有改变,仍然是int?
。
我知道我可以通过将!
应用于x
来告诉编译器闭嘴,但看起来我作弊了。在我使用的其他语言中,不得不退回到这种做法被认为是不好的做法,并且意味着你做错了什么。
我还有哪些其他选择?我能比在这里使用!
做得更好吗?
【问题讨论】:
您不必使用!
,但它不会“更好”。有时!
只是您应该使用的东西。否则它会从语言中删除。
id
是什么?我在代码中没有看到。请记住,它是可空的 reference 类型,而 int?
是可空值类型,因此警告与 int?
部分无关。
@madreflection 抱歉,我重命名了示例。 x 在我的实际代码中被命名为 id 。我编辑了我的帖子。并且警告绝对是关于 Nullableint?.Value
是int
,而actualNonNullValues
的推断类型正确的是List<int>
,而不是List<int?>
。
【参考方案1】:
在Select(x => x.Value)
中,x
的类型为int?
,因此编译器会立即警告您在该类型上调用.Value
可能会抛出异常。
这没有多大意义,因为您已经在 .Where(x => x.HasValue)
中检查了可空性。不幸的是,C# 编译器目前不理解 Select
将只接收非空值,因为它的上下文不理解 Where
方法语义。
你唯一的选择是!
,因为它说“我知道我在这里做什么。”
有一个语言问题跟踪此:https://github.com/dotnet/csharplang/issues/3951
【讨论】:
以上是关于可空类型产生警告,因为项目已启用可空引用类型的主要内容,如果未能解决你的问题,请参考以下文章
可空引用类型的注释只能在“#nullable”上下文中的代码中使用
可空引用类型意外 CS8629 可空值类型可能为带有临时变量的空