问题描述
让我们在 C# 中使用 string foo
变量。
为什么以下语句在语义上不等价?
if (!(foo is { } bar) || bar.Length == 0)
和
if (foo is not { } bar || bar.Length == 0)
对于 foo = null
,两者的行为似乎相同。
var foo = null;
if (!(foo is { } bar) || bar.Length == 0)
{
Console.WriteLine("bar");
}
if (foo is not { } baz || baz.Length == 0)
{
Console.WriteLine("baz");
}
但是对于 foo = "something"
,第一个语句有效,但第二个语句失败并显示 NullReferenceException
。
检查sharplab。
编辑:似乎是一个错误:https://github.com/dotnet/roslyn/issues/51996#issuecomment-803508111
解决方法
来自对问题的评论:
您是否会遇到 definite assignment 的问题? Per the docs,只有当 is
模式为真时,模式变量才被认为是明确分配的。 The changelog 链接到许多关于该主题的 git 问题。
来自文档的更多见解:
如果我们选择将此类工作推迟到以后(我建议这样做),我们可以说在 C# 9 中的 not
或 or
下,可能不会声明模式变量。然后,我们将有时间积累一些经验,以便深入了解以后放松的可能价值。