编译器错误地指示使用未分配的局部变量错误

Use of unassigned local variable error is incorrectly indicated by compiler

鉴于此代码:

private void TryIt(Dictionary<int, int> myDict)
{
    if (myDict?.TryGetValue(1, out int myValue) ?? false)
    {
        Console.Out.WriteLine(myValue); // <-- Error CS0165
    }
}

C# 编译器发出:

error CS0165: Use of unassigned local variable 'myValue'

但是当 ?. 运算符跳过对 TryGetValue() 的调用时,显然不可能引用 myValue。这是因为结果 null?? false 转换为 false

换句话说,如果 myDictnull?. 运算符将跳过对 TryGetValue() 的调用,留下 myValue 未分配。我明白了。

但是 ?? 运算符将始终评估向 false 的空传播,从而防止在这种情况下进入 if 块。

这在编译时很明显,那么为什么会出错?

我怀疑这可能与所有这些语法糖最终如何分解为实际的 .NET p 代码有关,但出错似乎仍然是错误的...

当不使用 .? 运算符时,我没有收到错误,这是预期的:

    if (myDict.TryGetValue(1, out int myValue))
    {
        Console.Out.WriteLine(myValue); // <-- NO ERROR
    }

就在我用.??? false的时候。

"But it is clearly not possible ..."

这是正确的,但编译器不会深入跟踪逻辑。

编译器可以推断出这一点,但请注意 myValue 的范围超出了 if 语句:

if (myDict?.TryGetValue(1, out int myValue) ?? false)
{
    Console.Out.WriteLine(myValue); // <-- Error CS0165
}
Console.Out.WriteLine(myValue); // myValue is in scope here

因此,虽然您可能希望编译器找出所有 ?.?? 逻辑,并且 if () { ... } 中的代码是一个特例,但这显然是一个被认为不够重要的功能。

myDict?.TryGetValue(1, out int myValue) 并不总是分配给 myValue.