为什么我的未初始化变量在TryParse中设置了值后又会再次取消赋值?

问题描述

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

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

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

        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++;
        }

解决方法

C#语言定值分析仅使用程序结构,而不使用数据值。

一个密切相关的问题:

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为true时,才分配x…但是编译器不会尝试跟踪此情况。它只是说“可能未分配”。结果是,在(4)处,即使您和我都可以,编译器也无法证明x已明确分配。

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

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

,

从流分析的角度来看,不能保证while循环将至少执行一次。当然,您会另外知道,因为您的条件涉及一个bool变量,该变量已初始化为false的值,但是编译器不够聪明,无法实现。

因此,如果它至少执行不到一次,inputBool仍将在末尾统一化,因此会出错。

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...