C# `out`未分配的变量。。。除非条件是内联的?

C# `out`未分配的变量。。。除非条件是内联的?,c#,out,C#,Out,我试图理解C#编译器在决定何时分配out变量时的规则 这里有一个让我困惑的例子。假设我们有一本字典: 如果条件稍微复杂一点,则是编译错误: var aBool = true; var found = aBool && dict.TryGetValue("b", out var val); if(found) { Console.WriteLine(val); //use of unassigned local variable val } 好的,我猜在这种情况下编译器不

我试图理解C#编译器在决定何时分配
out
变量时的规则

这里有一个让我困惑的例子。假设我们有一本
字典

如果条件稍微复杂一点,则是编译错误:

var aBool = true;
var found = aBool && dict.TryGetValue("b", out var val);
if(found)
{
    Console.WriteLine(val); //use of unassigned local variable val
}
好的,我猜在这种情况下编译器不会处理逻辑运算符。
…但如果我们将完全相同的条件内联移动,则又会出现彩虹:

var aBool = true;
if(aBool && dict.TryGetValue("b", out var val))
{
    Console.WriteLine(val); //compiles fine
}

为什么?

编译器无法保证变量
val
已初始化。在这种情况下,
aBool
是一些(非常量)布尔表达式。根据
aBool
的值,
val
可以初始化,也可以不初始化

为了帮助编译器,您必须使
aBool
const,这样编译器才能执行完整的分析。如果
aBool==true
val
肯定已初始化。如果
false
val
肯定没有初始化。然后,流分析可以确定
found
将被设置为与
val
变量的状态一致的值

const bool aBool = true;
...

第二种情况没有问题的原因是,
val
仅在
if
语句的主体中使用。只有当
aBool
true
TryGetValue()
调用成功(因此
val
被初始化)时,才会输入主体。

值得注意的是
&
工作而
&
不工作,例如
var found=aBool&dict.TryGetValue(“b”,out var val)正常。使用
&&
时,对
TryGetValue
的调用可能不会发生,因此
val
可能保持未初始化状态。。
var aBool = true;
if(aBool && dict.TryGetValue("b", out var val))
{
    Console.WriteLine(val); //compiles fine
}
const bool aBool = true;
...