Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

awaited Task<T> produces expression of type T? #47114

Closed
Youssef1313 opened this issue Aug 25, 2020 · 4 comments
Closed

awaited Task<T> produces expression of type T? #47114

Youssef1313 opened this issue Aug 25, 2020 · 4 comments
Labels
Resolution-Duplicate The described behavior is tracked in another issue

Comments

@Youssef1313
Copy link
Member

Originally reported in StackOverflow here. I'm not the original poster, just moved it here so the compiler team can have a look.

Version Used:

C# 8, Visual Studio 2019 16.7.2

Steps to Reproduce:

#nullable enable

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

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

Expected Behavior:

theString should be of type string not string?.

Actual Behavior:

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

@Youssef1313
Copy link
Member Author

Youssef1313 commented Aug 25, 2020

Update:
Just figured out this isn't only related to Task<T>!

public static string Test()
{
     return "Hi";
}

Calling it with: var x = Test() and hovering x shows it as nullable string (string?) instead of string.

Note: use explicit type code fix introduces the same issue, it replaces var with string?. The code fix relies on getting type info from semantic model. This might mean that the root cause is from there. However, I'm not sure.

@PathogenDavid
Copy link
Contributor

PathogenDavid commented Aug 25, 2020

I responded to the Stack Overflow question, here's my answer again for posterity:

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.

You might also be interested in the discussion at dotnet/csharplang#3591 I feel like I've seen others as well, but I can't find them right now.

@Youssef1313
Copy link
Member Author

Thanks, I'm closing this.

@sharwell
Copy link
Member

Duplicate of #45787

@sharwell sharwell marked this as a duplicate of #45787 Aug 25, 2020
@sharwell sharwell added the Resolution-Duplicate The described behavior is tracked in another issue label Aug 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution-Duplicate The described behavior is tracked in another issue
Projects
None yet
Development

No branches or pull requests

3 participants