C#做未分配的局部变量问题

时间:2019-03-12 08:53:35

标签: c#

我正在学习c#课程,并尝试升级我的用户输入法,以检查输入的控制台输入是否为整数。我已经将自己写到一个do while循环中,我知道这是行不通的,但是我在想办法找到既可以检查值又可以输入变量是否为整数的方法而苦苦挣扎。

因此,我在这里尝试做的是直到用户输入的输入为Integer,且介于最小值和最大值之间。但是我陷入困境,结果只设置为“ if”块中的值,而不是“ else”块中的值。除非将结果设置为某些未分配的变量,否则它将不会编译。而且我理解为什么,因为在一个分支中,我最终得到的是一个没有值的变量,并且在进行较小的比较时不会通过。您只能比较数字,不能比较null或字符串。

我应该放弃do-while循环以获取更聪明的东西吗?现在,在TryParse为false的情况下,我的“ hack”是将result设置为0。 这仅在用户不需要输入0时才有用,在这种情况下,整个操作不再有意义。

 static int readInt(string prompt, int low, int high) // METHOD readInt 
    {
        int result;
        bool succes;
        do
        {
            int temp;
            string intString = readString(prompt); 
            succes = Int32.TryParse(intString, out temp);
            if (succes)
            { Console.WriteLine("The string was a number within the limits, {0}.", intString);
                result = int.Parse(intString);
            }
            else
            {
                    Console.WriteLine("{0} is not a valid number between {1} and {2}", intString, low, high);
                result = 0;
            }

        } while (!succes && (result < low) || (result > high)); 
        return result;
    }

6 个答案:

答案 0 :(得分:0)

您可以更改“ result = int.Parse(intString);”在“ if”中加上“ return temp”;

您已经有TryParse中的数字,因此您无需再次解析它;在“ if”内部返回值实际上也消除了为“ else”内部的“ result”赋值的需要,您根本不需要“ result”)

Array
(
    [0] => Array
        (
            [id] => 3
            [title] => task 3
            [tech_user_id] => 1
            [dev_priority] => 1
        )
    [1] => Array
        (
            [id] => 1
            [title] => task 1
            [tech_user_id] => 1
            [dev_priority] => 2
        )

    [2] => Array
        (
            [id] => 2
            [title] => task 2
            [tech_user_id] => 1
            [dev_priority] => 3
        )


    [3] => Array
        (
            [id] => 4
            [title] => task 4
            [tech_user_id] => 1
            [dev_priority] => 4
        )

)

答案 1 :(得分:0)

使用while (true)循环并在获得有效结果时从循环内部返回可能会更容易。这是一个称为loop with one exit的结构化构造,因此可以使用(如果您担心结构化编程的话)。

例如:

static int readInt(string prompt, int low, int high) // METHOD readInt 
{
    while (true)
    {
        string intString = readString(prompt);

        if (Int32.TryParse(intString, out var result) && (result >= low) && (result <= high))
        {
            Console.WriteLine("The string was a number within the limits, {0}.", intString);
            return result;
        }
        else
        {
            Console.WriteLine("{0} is not a valid number between {1} and {2}", intString, low, high);
        }
    }
}

请注意,使用了相对较新的C#功能,即可以在使用时使用out关键字声明var变量的功能-请参见{{1 }}。

答案 2 :(得分:0)

或更简单的模式

int result;
string intString;

while (!int.TryParse(intString = Console.ReadLine(), out result) || result < low || result > high)
   Console.WriteLine($"{intString} is not a valid number between {low} and {high}");

Console.WriteLine("The string was a number within the limits, {result}.");

return result;

答案 3 :(得分:0)

您在代码中有几个错误。这有效:

    static int readInt(int low, int high)
    {
        int result;
        bool success;
        bool outOfLimits = false;
        do
        {
            Console.Write("Enter a number: ");
            string intString = Console.ReadLine();
            success = Int32.TryParse(intString, out result);
            if (!success)
            {
                Console.WriteLine("{0} is not a valid number.", intString, low, high);
                continue;
            }
            outOfLimits = result < low || result > high;
            if (outOfLimits)
                Console.WriteLine("The string was NOT a number between {1} and {2}.", intString, low, high);
            else
                Console.WriteLine("The string was a number within the limits, {0}.", intString);

        } while (!success || outOfLimits);
        return result;
    }

答案 4 :(得分:0)

尝试实施例行验证程序(无需通过!succes && (result < low) || (result > high)检查使代码太复杂):

  1. 如果用户input是有效整数(int.TryParse)?
  2. 有效范围内吗?

如果任何验证失败,请继续询问用户:

static int readInt(string prompt, int low, int high) 
{
    // Keep on looping until we return a valid result
    while (true) 
    {
        // Or 
        // Console.WriteLine(prompt);  
        // string input = Console.ReadLine();
        string input = readString(prompt); 

        int result = 0; // initialization: let the compiler be happy

        if (!int.TryParse(input, out result)) // Do we have an syntactically invalid input?
          Console.WriteLine($"{input} is not a valid integer number");
        else if (result < low || result > high) // If result is valid; is it out of range? 
          Console.WriteLine($"{input} is out of [{low}..{high}] range");
        else // result is valid integer and within the ranges: time to return it
          return result; 
    }
}

答案 5 :(得分:0)

当代码按照您的方式发展时,随着复杂度的提高,有时会变得不清楚。通常,这表明您应该重构它。

我会尝试通过将所有有效性检查移到一个方法中来使代码更清晰。然后您可以执行以下操作。

   static int readInt(string prompt, int low, int high) // METHOD readInt 
    {
        bool valid = false;
        int result = 0;
        while (!valid)
        {
            var intString = readString(prompt);
            valid = checkIfValid(intString, low, high, out result);
        }
        return result;
    }

    static bool checkIfValid(string s, int low, int high, out int result)
    {
        if (!Int32.TryParse(s, out result))
        {
            Console.WriteLine(s + " isn't an integer");
            return false;
        }

        if (result < low)
        {
            Console.WriteLine("Number is too low");
            return false;
        }

        if (result > high)
        {
            Console.WriteLine("Number is too high");
            return false;
        }

        return true;
    }