Non-nullable reference type: why is my object considered nullable by the compiler?

后端 未结 2 811
北荒
北荒 2021-01-19 05:39

I\'ve a project on which I enabled the new Nullable reference type feature

 enable
<         


        
相关标签:
2条回答
  • 2021-01-19 06:31

    Check out the specification on nullable reference types. It states that var infers an annotated type for reference types.

    The part under the heading nullable implicitly typed local variables reads:

    var infers an annotated type for reference types. For instance, in var s = ""; the var is inferred as string?.

    0 讨论(0)
  • 2021-01-19 06:35

    In the original implementation, foo would have been inferred as a Foo.

    However, people complained that this got in the way of things like:

    string? GetThing() => ...
    
    var result = "";
    if (condition)
    {
        result = GetThing();
    }
    

    If result is inferred as a string, then the result = GetThing() line causes a warning: GetThing() returns a string?, and there's a warning if you try and assign a string? to a string.

    The solution was to infer result as a string?, but the compiler knows that it's currently not null (its "flow state" is "NotNull").

    This means that:

    string? GetThing() => ...
    
    var result = "";
    
    // No warning, as the compiler knows that result isn't null
    int l1 = result.Length; 
    
    if (condition)
    {
        result = GetThing();
    }
    
    // Warning: the compiler knows 'result' might have been re-assigned
    int l2 = result.Length; 
    

    For other examples of the flow state at work, see things like:

    string? result = GetString();
    if (result == null)
        throw new Exception();
    
    // No warning: the compiler knows that result can't be null here: if it was,
    // the exception above would have been thrown
    int l1 = result.Length;
    
    string? result = GetString();
    
    // Warning: result might be null
    int l1 = result.Length; 
    
    // No warning: the compiler knows that result can't be null here: if it was,
    // the line above would have thrown
    int l2 = result.Length; 
    
    string result = "hello";
    if (result == null)
        Console.WriteLine("NULL!");
    
    // Warning: because we checked for null above, the compiler assumes that we
    // know something that it doesn't, and so result might be null.
    int l1 = result.Length;
    
    0 讨论(0)
提交回复
热议问题