有关 C# 8 可空引用类型的信息是否存储在 .NET 程序集中?

Ser*_*pov 4 c#-8.0 nullable-reference-types

使用 C# 8 编写且具有可为空引用类型的 Nuget 包的使用者是否会看到有关该包中定义的字段/参数的可为空性的信息?C# 8 编译器是否能够使用该信息发出适当的警告?

Pan*_*vos 5

是的,前提是他们也使用 C# 8 或更高版本并且已Nullable启用。BCL 类型已经发生过这种情况。

\n\n

C# 8 中的 NRT 不会引入新的类型。编译器会 在启用 NRT 的项目或文件中生成NullableContext和属性。Nullable它们用于分析代码并发出可空性警告。无论是否启用可为空性, astring和 astring?仍然是同一类型 a string

\n\n

Jon Skeet 的NullableAttribute And C# 8解释了这些属性如何工作以及它们如何影响包的公共 API,在本例中为 Noda Time。该包于 2019 年 2 月被移植到 C# 8。

\n\n

正如乔恩·斯基特所解释的:

\n\n
\n

C# 8 编译器在程序集中创建一个内部 NullableAttribute 类(如果我们的目标框架已经包含此类属性,我认为它不会\xe2\x80\x99t),并将该属性应用到与其相关的任何位置\xe2\x80\x99 。

\n
\n\n

这使得更改对于旧版 C# 编译器来说是透明的

\n\n

检查这个 Sharplab.io 示例。下面是简单的类:

\n\n
#nullable enable\nusing System;\npublic class C {\n    public void M(C c) {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

生成此中间 C# 代码:

\n\n
public class C\n{\n    [System.Runtime.CompilerServices.NullableContext(1)]\n    public void M(C c)\n    {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

虽然这样

\n\n
    public C M(C? c) {\n        return c ?? throw new ArgumentNullException(nameof(c));\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

生成此中间 C# :

\n\n
    [System.Runtime.CompilerServices.NullableContext(1)]\n    public C M([System.Runtime.CompilerServices.Nullable(2)] C c)\n    {\n        if (c != null)\n        {\n            return c;\n        }\n        throw new ArgumentNullException("c");\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n