为什么 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.
使用 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, invar s = "";
thevar
is inferred asstring?
.
因此,您不能在使用 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.