为什么我未初始化的变量在 TryParse 中设置了它的值后再次变为未分配?

Why does my uninitialised variable become unassigned again after it has its value set inside of TryParse?

变量 inputBool 在 while 循环外声明,然后在我尝试将 userInput 解析为布尔值时在 while 循环内设置。但是,一旦退出 while 循环,inputBool 将再次变为未声明状态!

但是,如果我用一个值 (EG false) 初始化 inputBool 变量,它将在 while 循环内部设置,然后将保持设置为在 TryParse 内部分配给它的任何值,即使在 while 循环退出后也是如此.

这是我想要的行为,但为什么当我不立即初始化变量时它不起作用?

        foreach (string question in questions)
        {
            bool isBool = false;
            // inputBool declared here.
            bool inputBool;
            string userInput;

            while (!isBool)
            {
                Console.WriteLine(question);
                userInput = Console.ReadLine();

                // inputBool gets assigned a value here in the TryParse.
                isBool = Boolean.TryParse(userInput, out inputBool);
                if (!isBool) Console.WriteLine("Please respond with 'true' or 'false'.");
            }

            // inputBool is unassigned here!
            answers[askingIndex] = inputBool;
            askingIndex++;
        }

从流程分析的角度来看,无法保证 while 循环至少会执行一次。当然,您知道其他情况,因为您的条件涉及一个初始化为值 falsebool 变量,但编译器不够智能,无法实现它。

因此,如果它至少没有执行一次,inputBool 仍然会在最后被初始化,因此会出错。

您需要确保变量在所有 代码路径中初始化。有两种可能的修复方法:

  1. while 更改为 do...while。那个保证至少执行一次,这确保变量被初始化。
  2. 将变量初始化为合理的默认值。

C# 语言definite-assignment 分析仅使用程序结构,不使用数据值。

一个密切相关的问题:

bool b = f();
int x;
// (1)
if (b) {
    x = 42;
    // (2)
    Trace.WriteLine(x); // ok
}
// (3)
if (b) {
    // (4)
    Console.WriteLine(x); // error, use of potentially unassigned variable x
}

在 (1) 处很明显,x 可能未分配(当然,偶数)。在 (2) 处,x 已明确分配。在 (3) 处,当且仅当 b 为真时 x 才被赋值……但编译器不会尝试跟踪这一点。它只是说“可能未分配”。结果在 (4) 处,编译器无法证明 x 已明确赋值,即使你我可以。

当编译器遇到 while 循环时,可以跳过该循环。因此,循环之前可能未分配的任何内容在循环之后仍可能未分配。即使你和我可以证明 你的 循环仅在变量被赋值时终止,这取决于数据值,而不是结构,并且 C# 不考虑它。

通过制作代码流程图,您可以非常轻松地重新创建编译器的明确赋值分析。在两条路径结合的任何一点,将布尔值 AND 应用于变量的状态。