将"if"语句条件移动到局部变量会使C#编译器不满意

Max*_*eev 7 c# compiler-construction

能否请您解释以下情况的原因.

今天我编写了代码(只更改了变量名称):

private void Foo() 
{
    int firstInteger, secondInteger;
    const string firstStringValue = "1", secondStringValue = "2";

    if (!string.IsNullOrWhiteSpace(firstStringValue) && int.TryParse(firstStringValue, out firstInteger) &&
        !string.IsNullOrWhiteSpace(secondStringValue) && int.TryParse(secondStringValue, out secondInteger))
    {
        // Using firstInteger and secondInteger here
        firstInteger++;
        secondInteger++;
    }
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到我决定将if条件移动到变量:

private void Foo()
{
    int firstInteger, secondInteger;
    const string firstStringValue = "1", secondStringValue = "2";

    bool firstIntegerAndSecondIntegerAreSpecified = 
        !string.IsNullOrWhiteSpace(firstStringValue) && int.TryParse(firstStringValue, out firstInteger) &&
        !string.IsNullOrWhiteSpace(secondStringValue) && int.TryParse(secondStringValue, out secondInteger);

    if (firstIntegerAndSecondIntegerAreSpecified)
    {
        // Use firstInteger and secondInteger here
        firstInteger++;
        secondInteger++;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在编译器强调firstIntegersecondInteger变量,错误"在访问之前可能没有初始化局部变量".

但为什么?我做的唯一一件事是重构代码.而且我认为逻辑是一样的.

Jon*_*eet 9

编译器(或更确切地说,规范)没有发现firstIntegerAndSecondIntegerAreSpecified调用值和调用之间的关系int.TryParse.在第一种形式中,如果两个调用int.TryParse都已执行,则执行只会进入正文,因此两者都有明确赋值(由于out参数).因此if块中没有问题.

明确赋值的规则不包括firstIntegerAndSecondIntegerAreSpecified仅在两个调用都已成立时才为真的想法,因此在if块的主体中,变量仍未明确赋值,因此错误.


Guf*_*ffa 6

编译器的构建不够巧妙,无法确定布尔变量中的真值可确保设置整数值.编译器仅跟踪执行路径,而不是可变值.

在第一种情况下,编译器知道如果没有TryParse调用设置变量,就不可能输入if语句.在第二种情况下,if语句与TryParse调用分离,因此编译器必须跟踪变量值以找出关系.