这种代码通常可以在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
,但这也没有用。
谢谢!
答案 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语句内部和之后使用它。