问题
If I have the C# 8 code:
class Foo {}
And later:
#nullable enable
var bar = new Foo();
Then the type of bar
is Foo?
. This seems clearly incorrect, as a new
expression can't return null
. Why would bar
be a nullable reference? I even looked up the Nullable Reference Type Specification, and found the following:
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)- ...
And also:
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 typeC?
and the null state ofE
is "not null" then the type inferred forx
isC
. Otherwise, the inferred type is the type ofE
.The nullability of the type inferred for
x
is determined as described above, based on the annotation context of thevar
, just as if the type had been given explicitly in that position.
So based on everything I can find in the spec, bar
in my very simple example should be of type Foo
, not type Foo?
. What am I missing?
回答1:
If var
were to infer its nullability from the expression, then in many instances you would not be able to assign a null
to it later on. For example, var s = "";
.
There was a discussion to allow var?
to express "the nullable version of the type", but it had several issues. Would the regular var
be restricted to infer a non-nullable type?
If yes, then (1) we're creating adoption pain as users need to add more ?
annotations, (2) we have an inconsistent nullability with var
pattern which had already shipped, (3) there are some questions with nullable value types (int?
).
If no, then the intent of the code would not be very clear. var?
would clearly indicate a nullable type, but var
would be a mixed bag of nullable and non-nullable.
The decision to infer a nullable type for var
was recorded in the LDM notes from 2019-12-18.
来源:https://stackoverflow.com/questions/62685673/in-c-sharp-8-why-does-type-inference-on-new-expressions-result-in-nullable-refe