为啥 C# 中的 async/await 会返回可为空的值,即使被告知不要这样做?
Posted
技术标签:
【中文标题】为啥 C# 中的 async/await 会返回可为空的值,即使被告知不要这样做?【英文标题】: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
对吗?
这能回答你的问题吗? Why does Visual Studio Type a Newly Minted Array as Nullable?
Intellisense 还会向您显示一条消息,例如:“'theString' is not null here.”,因此您需要正确/安全地使用该变量的信息应该随时可用。
【参考方案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
总是可以为空的。很有道理,我想我被送错了轨道,认为它与异步有关
我的想法完全一样,我们有一些非空变量...以上是关于为啥 C# 中的 async/await 会返回可为空的值,即使被告知不要这样做?的主要内容,如果未能解决你的问题,请参考以下文章
深入了解异步async/await,为啥这种异步的性能这么高?异步的原理,本文彻底来个说明