C#变量范围和“switch”语句?

时间:2012-03-20 00:11:04

标签: c# scope

这种代码通常可以在PHP中运行,但由于C#中的范围要严格得多,所以并非如此。我不知道如何编写这段代码而不重复自己。

    static double Cube()
    {
        Console.Write("Enter the side length of the cube: ");
        try
        {
            double x = Convert.ToDouble(Console.Read());
            return Math.Pow(x, 3);
        }
        catch (FormatException)
        {
            Console.WriteLine("Invalid input, please enter a number.");
            Cube();
        }
        return 1;
    }

..稍后在Main():

            switch (choice)
            {
                case 0:
                    return;
                case 1:
                    double final = Cube();
                    break;
                default:
                    Console.WriteLine("Please enter 0 or 1.");
                    Main();
                    break;
            }
            Console.WriteLine("The volume is: {0}", Convert.ToString(final));

Cube()方法工作正常,但在我看来它很混乱(最后return 1让编译器开心)。但是出现了一个错误当前上下文中不存在“final”这个名称。它无法找到最终结果。因此,我所看到的唯一方法就是将Console.WriteLine语句放在double final = Cube()之后。

我也尝试在开关外声明double final;,然后在每个案例中设置final,但这也没有用。

谢谢!

3 个答案:

答案 0 :(得分:19)

你是对的:这是一团糟。重来。

您的根本问题在于您没有将您的顾虑分开。您有一个方法可以同时执行用户输入,输入验证,重试逻辑和数学运算。你应该为每个人制定方法。

此外,使用TryParse来处理失败案例,而不是异常处理。

最后,递归完全是错误的工具。问题必须具有以下要通过递归解决的特征:

  • 一个简单的基础案例。
  • 可以减少一系列较小的问题。
  • 可以结合较小问题的解决方案来解决更大的问题。
  • 重复地减小问题最终会导致轻微的问题。

您的问题有 none 这些属性,因此递归自动是错误的工具。您需要的工具是循环

static void Main()
{
    double x = ObtainDoubleFromUser(
        "Enter the side length of the cube: ", 
        "Please enter a number: ");
    Console.WriteLine("The volume is {0}", Cube(x));
}

static double ObtainDoubleFromUser(string firstMessage, string failureMessage)
{
    Console.Write(firstMessage);
    while(true)
    {
        double result;
        if (Double.TryParse(Console.Read(), out result))
            return result;
        Console.Write(failureMessage);
    }
}

static double Cube(double x)
{
    return Math.Pow(x, 3);
}

这一切都有意义吗?如果可能,您希望避免递归和异常处理。并将您的疑虑分开。

答案 1 :(得分:4)

如果您想从final范围之外访问switch,则必须在该范围之外声明它。如果您引用final并且存在不允许将值设置为final的代码路径,则编译器将“生气”。

在php中,当你没有为它分配任何内容时,final会神奇地为0。尝试在切换之前声明final,然后在每个case语句中为其分配一个值,包括default个案。

答案 2 :(得分:2)

将变量声明放在switch语句之前:

double final = 0.0;
switch(choice)
{ 
    ...
}

然后只需在switch语句中使用该变量:

case 1:
    final = Cube();
    break;

在C#中,必须先声明变量才能使用它们。在您的代码中,声明仅限于switch语句的范围。在switch语句之前声明变量可确保它在方法范围内,允许在switch语句内部和之后使用它。