【发布时间】:2020-09-14 10:35:02
【问题描述】:
在启用了可为空引用类型的 C# 8 中,为什么以下内容不会引发编译器警告或错误?
var strings = new string[1];
LogList(strings);
public void LogList(IEnumerable<string> strings) {
foreach(var s in strings) {
Console.WriteLine(s.ToString());
}
}
我期待一个编译器警告或错误,因为数组有未初始化的元素,而 IEnumerable<String> 中的 String 是不可为空的。相反,当调用 s.ToString() 时,我会在运行时收到 NullReferenceException。
如果我指出数组元素可以为空,string?[],或者使用带有可以为空的字符串的集合,List<string?>,那么编译器会警告我将其传递给 LogList,它需要一个(非空)IEnumerable非空字符串。为什么上面的代码示例没有生成类似的警告?
我查看了一些关于可空引用类型的 SO 问题,但没有一个专门回答这个问题。
(在 LINQPad 6.9.15 中测试的代码)
【问题讨论】:
-
涉及初始化的可空规则有许多例外,所有这些都围绕着现有的语义,例如数组和结构,它们具有隐式初始化。请参阅重复的,当然还有引用的文章,devblogs.microsoft.com/dotnet/…。简短的版本:C# 语言设计者认为对这些场景的警告会产生过多的误报,因此他们故意将它们排除在分析之外。您将数组声明为具有不可为空的元素,并且编译器相信您。所以没有警告。
标签: c# c#-8.0 nullable-reference-types