为什么 C# 中的 async/await return 可为空值,即使被告知不要这样做?

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

使用 C#8,Visual Studio 2019 16.7.2,给定以下 C# 代码:

#nullable enable

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

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

将 Intellisense 悬停在 theString 上会显示 局部变量(字符串?)theString

的工具提示

我的 GetStringAsync 方法从不 returns 可为空的字符串,但该变量被推断为可为空。

这是智能感知错误吗?还是由于 await 的某种工作方式,theString 实际上可能为空?

是否存在更深层次的问题?

这是by-design,与await没有关系。

var 始终可为空,来自 the spec:

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

因此,您不能在使用 var 时将 theString 明确指定为 non-nullable。如果您希望它是 non-nullable,请明确使用 string


至于为什么:简而言之,就是允许这样的场景:

#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;
    }
}

编译器将使用流分析来确定变量在任何给定点是否为空。 You can read more about the decision here.