我最近尝试为我的 C# 项目启用可空上下文。它很棒,主要是因为如果我使用不可为 null 的类型,我可以依靠引用来存储正确的对象。
或者至少我是这么想的。不幸的是,当我使用外部库时,有时会在不可为空类型中看到空引用。例如
如果我使用
System.xml.serialization.xmlserialier.
Deserialize
()
并且生成的对象具有不可为空的字段。反序列化会将 null 放入返回对象的字段中 - 即使它们不可为 null。
我还使用了一个名为 AutoMapper 的第三方库。该库具有类似的行为 - 它只是生成违反不可为空假设的对象,并且我没有看到更改此设置的选项。
遇到这种情况你会如何处理?我不确定是否
我只是错误地选择了我的库,并且有更好的库不会将 null 写入不可为空的字段。
我必须手动检查所有对象是否来自外部代码?
我完全错过了这些不可空类型的要点......?我认为这个想法是,如果我的代码没有发出编译器警告,我可以依赖这些类型不具有 null。
我尝试为上述库找到具体的解决方案。然而,两者似乎都没有意识到并且没有提供“如果为空则抛出异常”或类似的标志。
...如果我使用不可为 null 的类型,我可以依靠引用来存储正确的对象。
确实如此,但这并不是硬性的运行时保证。这是编译时的“静态代码分析”检查,很容易“覆盖”:
您可以使用 null-forgiving 运算符
!
将 null 分配给不可为 null 的引用类型的变量或字段。
可以使用反射来赋值null。
调用 C# 库的 VB 代码将很乐意忽略库中所有可为空的注释。
在您编译的代码中,该字段在技术上仍然是“可为空”。当然,编译器会设置有用的属性,.NET 6+ 甚至有一个 API 来检查这些属性,但它仍然“只是”一个注释,而不是运行时类型检查,这将导致 CLR 退出一个例外。
遇到这种情况你会如何处理?
小心反序列化、对象关系映射器和其他使用反射动态填充对象的库。它们通常是在可空引用类型出现之前编写的。检查文档是否尊重可为空属性。如果没有,请在使用对象之前验证它们。