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

C# 编译器错误地指示未分配局部变量错误的使用,c#,compiler-errors,nullable,out,null-propagation-operator,C#,Compiler Errors,Nullable,Out,Null Propagation Operator,鉴于此代码: private void TryIt(Dictionary<int, int> myDict) { if (myDict?.TryGetValue(1, out int myValue) ?? false) { Console.Out.WriteLine(myValue); // <-- Error CS0165 } } 但是当操作符跳过对TryGetValue()的调用时,显然不可能引用myValue。操作符。这是因为产

鉴于此代码:

private void TryIt(Dictionary<int, int> myDict)
{
    if (myDict?.TryGetValue(1, out int myValue) ?? false)
    {
        Console.Out.WriteLine(myValue); // <-- Error CS0165
    }
}
但是当
操作符跳过对
TryGetValue()
的调用时,显然不可能引用
myValue
操作符。这是因为产生的
null
转换为
false
??错误

换句话说,如果
myDict
null
,则
.
运算符将跳过对
TryGetValue()
的调用,使
myValue
保持未分配状态。我明白了

但是
运算符随后将始终计算空传播到
false
,在这种情况下防止进入if块

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

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

如果不使用
运算符,则不会出现错误,这是预期的:

    if (myDict.TryGetValue(1, out int myValue))
    {
        Console.Out.WriteLine(myValue); // <-- NO ERROR
    }
if(myDict.TryGetValue(1,out int myValue))
{
Console.Out.WriteLine(myValue);//
“但这显然是不可能的……”

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

编译器可以推断出这一点,但请注意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)??false)
{

Console.Out.WriteLine(myValue);//我正试图弄清楚`?false`的意图是什么,因为TryGetValue返回bool。我怀疑其意图更接近于`(if(myDict?.TryGetValue(1,Out int myValue)?true:false)`但是……也许我遗漏了什么“as
.TryGetValue()
返回bool”-是的,但是
?.TryGetValue()
可能返回bool或null,因此它变为
bool?
根据C语言规范,错误消息并不错误。编译器几乎不可能在100%的时间内正确计算执行流,因此必然存在限制。出于实际原因,这些限制相当狭窄,排除了sc启用您想要工作的场景。请参阅标记的副本。第一个场景正是您正在询问的场景,您应该自己找到它,而不是问一个新问题。第二个场景更一般地解决相同的基本问题(即非常量
if
表达式使
if
主体可访问)
if (myDict?.TryGetValue(1, out int myValue) ?? false)
{
    Console.Out.WriteLine(myValue); // <-- Error CS0165
}
Console.Out.WriteLine(myValue); // myValue is in scope here