有关 C# 8 可空引用类型的信息是否存储在 .NET 程序集中?
Is the information about C# 8 nullable reference types stored in a .NET assembly?
使用 C# 8 编写的具有可为空引用类型的 Nuget 包的消费者是否会看到有关该包中定义的字段/参数的可空性信息? C# 8 编译器能否使用该信息发出适当的警告?
是的,前提是他们也使用 C# 8 或更高版本并且启用了 Nullable
。这已经发生在 BCL 类型上。
C# 8 中的 NRT 没有引入一种新的类型。编译器在启用 NRT 的项目或文件中生成 NullableContext
和 Nullable
属性。这些用于分析代码并发出可空性警告。无论是否启用可空性,string
和 string?
仍然是同一类型,即 string
。
Jon Skeet 的 NullableAttribute And C# 8 解释了这些属性如何工作以及它们如何影响包的 public API,在本例中为 Noda Time。该软件包已于 2019 年 2 月移植到 C# 8。
正如 Jon Skeet 解释的那样:
The C# 8 compiler creates an internal NullableAttribute class within the assembly (which I assume it wouldn’t if we were targeting a framework that already includes such an attribute) and applies the attribute anywhere it’s relevant.
这使得更改对旧的 C# 编译器透明
检查 this Sharplab.io example。下面简单的class:
#nullable enable
using System;
public class C {
public void M(C c) {
}
}
生成此中间 C# 代码:
public class C
{
[System.Runtime.CompilerServices.NullableContext(1)]
public void M(C c)
{
}
}
同时 this :
public C M(C? c) {
return c ?? throw new ArgumentNullException(nameof(c));
}
生成此中间 C#:
[System.Runtime.CompilerServices.NullableContext(1)]
public C M([System.Runtime.CompilerServices.Nullable(2)] C c)
{
if (c != null)
{
return c;
}
throw new ArgumentNullException("c");
}
}
使用 C# 8 编写的具有可为空引用类型的 Nuget 包的消费者是否会看到有关该包中定义的字段/参数的可空性信息? C# 8 编译器能否使用该信息发出适当的警告?
是的,前提是他们也使用 C# 8 或更高版本并且启用了 Nullable
。这已经发生在 BCL 类型上。
C# 8 中的 NRT 没有引入一种新的类型。编译器在启用 NRT 的项目或文件中生成 NullableContext
和 Nullable
属性。这些用于分析代码并发出可空性警告。无论是否启用可空性,string
和 string?
仍然是同一类型,即 string
。
Jon Skeet 的 NullableAttribute And C# 8 解释了这些属性如何工作以及它们如何影响包的 public API,在本例中为 Noda Time。该软件包已于 2019 年 2 月移植到 C# 8。
正如 Jon Skeet 解释的那样:
The C# 8 compiler creates an internal NullableAttribute class within the assembly (which I assume it wouldn’t if we were targeting a framework that already includes such an attribute) and applies the attribute anywhere it’s relevant.
这使得更改对旧的 C# 编译器透明
检查 this Sharplab.io example。下面简单的class:
#nullable enable
using System;
public class C {
public void M(C c) {
}
}
生成此中间 C# 代码:
public class C
{
[System.Runtime.CompilerServices.NullableContext(1)]
public void M(C c)
{
}
}
同时 this :
public C M(C? c) {
return c ?? throw new ArgumentNullException(nameof(c));
}
生成此中间 C#:
[System.Runtime.CompilerServices.NullableContext(1)]
public C M([System.Runtime.CompilerServices.Nullable(2)] C c)
{
if (c != null)
{
return c;
}
throw new ArgumentNullException("c");
}
}