在值类型上通过 Nulllable.Value 属性 宽恕 null 时收到警告

Getting warning when forgiving null through Nulllable.Value property on value type

我试图重现应用于值类型的允许空值的代码,但它没有生成任何警告:dotnetfiddle.net。在实际代码中,我收到警告。我实际上是在使用 .NET Core 6.0 进行编译。

我在代码库上收到多个编译时警告,其中一些与允许空值的代码有关。我正在尝试使用 SomeNullableValue.ValueSomeNullableValue!,但编译器抱怨我可能以两种方式将 null 参数传递给函数。

我现在处理的案例是一个 enum ,它最初是空的,但稍后在同一控制流中被分配;在这种情况下,它是 Ast.ContStmtTarget? t,其中 Ast.ContStmtTargetenum:

NextToken();
Ast.ContStmtTarget? t = null;
if (CurrentToken.Type == Token.Keyword) {
    switch (CurrentToken.StringValue) {
        case "do": t = Ast.ContStmtTarget.Do; break;
        case "for": t = Ast.ContStmtTarget.For; break;
        case "loop": t = Ast.ContStmtTarget.Loop; break;
        case "while": t = Ast.ContStmtTarget.While; break;
    }
}
if (!t.HasValue) {
    FatalError(0x80A0400, GetTokenSpan());
}
r = new Ast.ContStmt(t.Value);

编译器在最后一行 r = ...; 中输出警告,该列指向 t.Value。此外,Ast.ContStmt 构造函数采用不可为 null 的值(enum)。

...\Parser.cs(1410,38): warning CS8629: Nullable value type may be null.

我已将可编译项目放​​在 GitHub (dotnet build):

编译器警告您可以使用 t == null 到达该行。 FatalError return 吗?我假设它抛出但编译器不知道

if (!t.HasValue) {
    FatalError(0x80A0400, GetTokenSpan());
} else{
   r = new Ast.ContStmt(t.Value);
}

你可以用 DoesNotReturnAttribute 标记 FatalError 来帮助编译器确定 if 之后的代码在 !t.HasValue 的情况下无法访问,否则编译器无法验证代码不会实际上被称为:

[DoesNotReturn]
private void FatalError(int msgId, Span? span, Dictionary<string, object>? vars = null) {
    throw new SyntaxException(Program.Collect(new Problem(msgId, false, vars, span.Value)));
}