Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does async/await in C# return nullable values even when told not to?

Using C#8, Visual Studio 2019 16.7.2, given the following C# code:

#nullable enable

public async Task<string> GetStringAsync(); ...

public async void Main()
{
    var theString = await GetStringAsync();
    ...
}

Intellisense hovering over theString shows a tooltip of local variable (string?) theString

My GetStringAsync method never returns a nullable string, yet the variable is inferred as being nullable.

Is this an intellisense bug? Or is there something deeper going on where theString can actually be null due to some way that await works?

like image 941
Orion Edwards Avatar asked Aug 25 '20 11:08

Orion Edwards


Video Answer


1 Answers

This is by-design and does not have to do with the await.

var is always nullable, from the spec:

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

As such, you can't explicitly specify theString as non-nullable when you use var. If you want it to be non-nullable, use string explicitly.


As to why: In short, it's to allow scenarios like this:

#nullable enable

public async Task<string> GetStringAsync(); ...

public async void Main()
{
    var theString = await GetStringAsync();
    
    if (someCondition)
    {
        // If var inferred "string" instead of "string?" the following line would cause
        // warning CS8600: Converting null literal or possible null value to non-nullable type.
        theString = null;
    }
}

The compiler will use flow analysis to determine whether or not the variable is null at any given point. You can read more about the decision here.

like image 90
Pathogen David Avatar answered Sep 19 '22 12:09

Pathogen David