2012-03-20 187 views
2

这种代码通常在PHP中工作,但是由于范围在C#中要严格得多,事实并非如此。我无法想出一种不重复自己的方式来编写这段代码。C#变量作用域和“switch”语句?

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

..Later在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'在当前上下文中不存在。它无法找到最终的。因此,让我看到的这个工作的唯一方法是在double final = Cube()后面放置Console.WriteLine语句。

我也试过在开关外面声明double final;,然后在每种情况下只设置final,但那也没有奏效。

谢谢!

+1

“还没有工作”(与其他事情尝试)是错误的/误导。他们会1)工作或2)导致不同的错误。 – 2012-03-20 00:26:49

+0

因为你对Cube的定义很混乱,你必须把'return 1'。它做了太多的事情,并且你在catch中使用递归也不是很干净。该函数必须返回一个值,所以你任意选择1作为失败返回。如果你不喜欢那样,移动Math.Pow并决定你在哪里可以真正得到正确的错误行为。 – CodexArcanum 2012-03-20 00:34:08

回答

4

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

在php中,final在你没有分配任何东西时会奇迹般地为0。尝试在切换前声明final,然后在每个case声明(包括default个案)中为其分配一个值。

+0

这样做,谢谢! – Scott 2012-03-20 00:27:04

2

将您的开关语句之前的变量声明:

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

然后,只需使用该变量的switch语句:

case 1: 
    final = Cube(); 
    break; 

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

19

你说得对:这是一团糟。重来。

你的根本问题是你没有分开你的担忧。您有一种方法可以同时进行用户输入,输入验证,重试逻辑和数学运算。你应该为每个人制作方法。

另外,使用TryParse来处理失败的情况,而不是异常处理。

最后,递归是完全错误的使用工具。一个问题必须具有以下特点通过递归来解决:

  • 甲琐碎基础案例。
  • 可以简化为一组较小的问题。
  • 小问题的解决方案可以结合使用来解决更大的问题。
  • 重复制作一个更小的问题最终会变成一件小事。

你的问题具有这些特性的没有,所以递归是自动错误的工具。你想要的工具是循环

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

这一切都有意义吗?如果可能的话,你想避免递归和异常处理。并保持你的关注分离。

+0

我只想在12月份完全错过这个梦幻般的答案而感到歉意 - 我喜欢认为自己已经超越了'给予代码'的程序员,因为我明显是当我发布这个问题时。谢谢! – Scott 2015-03-28 01:26:06