在 C# 8 中,为什么对新表达式的类型推断会导致可为空的引用?

In C# 8, why does type inference on new expressions result in nullable references?

如果我有 C# 8 代码:

class Foo {}

以后:

#nullable enable
var bar = new Foo();

那么bar的类型就是Foo?。这显然是不正确的,因为 new 表达式不能 return null。为什么 bar 是一个可为空的引用?我什至查阅了 Nullable Reference Type Specification,发现了以下内容:

Expressions that are never null

The null state of the following expression forms is always "not null":

  • ...
  • new expressions (object, delegate, anonymous object and array creation expressions)
  • ...

还有:

Type inference for var

The type inferred for local variables declared with var is informed by the null state of the initializing expression.

var x = E;

If the type of E is a nullable reference type C? and the null state of E is "not null" then the type inferred for x is C. Otherwise, the inferred type is the type of E.

The nullability of the type inferred for x is determined as described above, based on the annotation context of the var, just as if the type had been given explicitly in that position.

因此,根据我在规范中可以找到的所有内容,在我非常简单的示例中,bar 应该是 Foo 类型,而不是 Foo? 类型。我错过了什么?

如果 var 从表达式中推断它的可空性,那么在许多情况下,您以后将无法为其分配 null。例如,var s = "";。 有一个讨论允许 var? 表达“类型的可空版本”,但它有几个问题。常规 var 会被限制为推断不可为 null 的类型吗?

如果是,那么 (1) 我们正在制造采用痛苦,因为用户需要添加更多 ? 注释,(2) 我们与已经发布的 var 模式存在不一致的可空性, (3) 有一些题的值类型可以为nullable (int?)。 如果不是,那么代码的意图就不会很清楚。 var? 将清楚地指示可空类型,但 var 将是可空类型和不可空类型的混合体。

var 推断可空类型的决定记录在 LDM notes from 2019-12-18 中。