不可空类型被库设置为空

问题描述 投票:0回答:1

我最近尝试为我的 C# 项目启用可空上下文。它很棒,主要是因为如果我使用不可为 null 的类型,我可以依靠引用来存储正确的对象。

或者至少我是这么想的。不幸的是,当我使用外部库时,有时会在不可为空类型中看到空引用。例如

  • 如果我使用

    System.xml.serialization.xmlserialier.
    Deserialize
    ()
    并且生成的对象具有不可为空的字段。反序列化会将 null 放入返回对象的字段中 - 即使它们不可为 null。

  • 我还使用了一个名为 AutoMapper 的第三方库。该库具有类似的行为 - 它只是生成违反不可为空假设的对象,并且我没有看到更改此设置的选项。

遇到这种情况你会如何处理?我不确定是否

  • 我只是错误地选择了我的库,并且有更好的库不会将 null 写入不可为空的字段。

  • 我必须手动检查所有对象是否来自外部代码?

  • 我完全错过了这些不可空类型的要点......?我认为这个想法是,如果我的代码没有发出编译器警告,我可以依赖这些类型不具有 null。

我尝试为上述库找到具体的解决方案。然而,两者似乎都没有意识到并且没有提供“如果为空则抛出异常”或类似的标志。

c# .net nullable nullable-reference-types non-nullable
1个回答
1
投票

...如果我使用不可为 null 的类型,我可以依靠引用来存储正确的对象。

确实如此,但这并不是硬性的运行时保证。这是编译时的“静态代码分析”检查,很容易“覆盖”:

  1. 您可以使用 null-forgiving 运算符

    !
    将 null 分配给不可为 null 的引用类型的变量或字段。

  2. 可以使用反射来赋值null。

  3. 调用 C# 库的 VB 代码将很乐意忽略库中所有可为空的注释。

在您编译的代码中,该字段在技术上仍然是“可为空”。当然,编译器会设置有用的属性,.NET 6+ 甚至有一个 API 来检查这些属性,但它仍然“只是”一个注释,而不是运行时类型检查,这将导致 CLR 退出一个例外。

遇到这种情况你会如何处理?

小心反序列化、对象关系映射器和其他使用反射动态填充对象的库。它们通常是在可空引用类型出现之前编写的。检查文档是否尊重可为空属性。如果没有,请在使用对象之前验证它们。

© www.soinside.com 2019 - 2024. All rights reserved.