【问题标题】:Why does async/await in C# return nullable values even when told not to?为什么 C# 中的 async/await 会返回可为空的值,即使被告知不要这样做?
【发布时间】:2020-12-14 02:38:39
【问题描述】:

使用 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 方法从不返回可为空的字符串,但该变量被推断为可为空。

这是一个智能感知错误吗?或者,由于await 的某些工作方式,theString 实际上可能为空,是否还有更深层次的事情发生?

【问题讨论】:

  • 通过GitHub issue 重定向到编译器团队。我们应该很快得到答案,这是一个错误,不是错误,还是设计使然。
  • 这不是 vs 2019 版本“Microsoft Visual Studio Community 2019 16.6.5”的行为。在这个版本中,智能感知显示“字符串”。
  • 但是,如果您将theString 声明为string theString,它将是string 对吗?
  • Intellisense 还会向您显示一条消息,例如:“'theString' is not null here.”,因此您需要正确/安全地使用该变量的信息应该随时可用。

标签: c# visual-studio async-await nullable-reference-types


【解决方案1】:

这是设计使然,与await 无关。

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

var 推断引用类型的注释类型。例如,在var s = ""; 中,var 被推断为string?

因此,当您使用var 时,您不能将theString 显式指定为不可为空。如果您希望它不可为空,请明确使用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.

【讨论】:

  • 谢谢!我不知道var 总是可以为空的。很有道理,我想我被送错了轨道,认为它与异步有关
  • 我的想法完全一样,我们有一些非空变量...
猜你喜欢
  • 1970-01-01
  • 2018-03-29
  • 2016-06-02
  • 1970-01-01
  • 2021-12-18
  • 2015-06-30
  • 1970-01-01
  • 2017-10-26
相关资源
最近更新 更多