有人可以向我解释 C# 8 可为空的引用类型吗?

Can someone please explain C# 8 nullable reference type to me?

三行代码,我已经有警告:

var serializer = new XmlSerializer(typeof(Files));

using var fs = new FileStream(@"Files.xml", FileMode.Open, FileAccess.Read, FileShare.Read);

var files = (Files)serializer.Deserialize(fs);

serializerfs 显然对任何类型的静态代码分析器都不为空。我还没有对 files 做任何事情。

然而在作业中我收到编译器警告CS8600: Converting null literal or possible null value to non-nullable type

'serializer' is not null here.

嗯,你想说什么?

解决方案显然是这样写最后一行:

var files = (Files)serializer.Deserialize(fs)!;

但是除了消除编译器警告或者它应该如何以任何方式改进我的代码之外,我不知道我用它完成了什么。

编译器无法计算出 运行 时的情况。这样做可能很容易,也可能很难,也可能不可能。它不会尝试。如果您调用一个 CAN return null 的方法,那么您不能将其结果分配给一个不能 null.

的变量

使用 ! 运算符有点像强制转换。当你进行强制转换时,你是在告诉编译器你负责确保理论上可以指向各种类型对象的引用实际上将指向 [=21 处的特定类型的对象=] 时间。类似地,! 告诉编译器您有责任确保理论上可能是 null 的引用实际上不会 null 在 运行 时间。如果您不履行该责任,那么可能会在 运行 时抛出异常,就像您指定的转换失败时一样。

The solution apparently is to write the last line like this:

您的解决方案是错误的,警告是因为 XmlSerializer.Deserialize 可能 return null。现在您想将可能的空值 object? 转换为 non-nullable 类型 Files,但您不能保证反序列化总是成功。所以抑制这个警告的正确方法是:

var files = (Files?)serializer.Deserialize(fs);