多年来,我的主要语言是Perl,我定期对用户输入进行验证,没有任何问题。现在,我使用了大量的C#,并希望迁移到通过验证用户输入和从抛出的异常恢复/返回的抛出/捕获样式。我正在使用一种非常天真(即,愚蠢)的方法来做这件事,我觉得迫切需要转向一些更成熟、更不愚蠢的东西。我复制了一个从提示符返回整数的函数。我正在通过使用可怕的GOTO语句从用户错误中恢复。有什么更好的方法来做这件事?
谢谢,CC。
private static int GetInput(string v)
{
begin:
Console.Write(v);
string strradius = Console.ReadLine();
int intradius;
try
{
intradius = int.Parse(strradius);
if (intradius < 1)
throw new ArgumentOutOfRangeException();
}
catch (ArgumentNullException)
{
Console.WriteLine("You must enter a value.");
goto begin;
}
catch (FormatException)
{
Console.WriteLine("You must enter a valid number.");
goto begin;
}
catch (ArgumentOutOfRangeException)
{
Console.WriteLine("Your number is out of range");
goto begin;
}
catch (Exception ex)
{
Console.WriteLine(ex);
goto begin;
}
finally
{
Console.WriteLine("Okay");
}
return intradius;
} 发布于 2018-08-21 23:12:31
首先,关于何时使用goto的一个好的经验规则是永远不会的。真的,除了少数非常罕见的特殊情况外,你永远不会想要使用它。
接下来,对于您的问题,使用异常来验证输入通常是个坏主意。就像大多数人指出的那样,它很贵。例外情况应该用来处理特殊情况,所以我实际上根本不使用它们。
相反,您可以使用do-while循环,只要用户输入不正确的输入,就可以重复。一旦得到适当的输入,就退出循环。如果发生异常,则不应真正继续该过程。要么在外部处理它(即,方法中没有try-catch ),要么如果必须执行try-catch,那么只需打印一条消息并退出该方法。但是,对于这种方法,我不会使用异常处理。另外,将返回类型实际更改为bool也是一个好主意,因此您向外部世界表明该方法是否通过返回类型成功。您可以使用out参数实际返回转换后的int。
private static bool GetInput(string msg, out int converted)
{
bool result = false;
converted = 0;
do
{
Console.Write(msg);
string str = Console.ReadLine();
result = int.TryParse(str, out converted);
if (result && converted < 1)
{
Console.WriteLine("Your number is out of range");
result = false;
}
if (!result && string.IsNullOrEmpty(str))
{
Console.WriteLine("You must enter a value.");
}
if (!result && !string.IsNullOrEmpty(str))
{
Console.WriteLine("You must enter a valid number.");
}
} while (!result);
return result;
}发布于 2018-08-21 23:29:34
在C#代码中使用goto语句受到高度反对,因为它使代码难以读取、调试和维护(要获得更多信息,请阅读这)。循环、if/ goto语句或方法调用可以用来代替goto语句。此外,try \ catch块应该被谨慎地使用,以捕获您无法处理的异常。
在您的例子中,我们可以使用一个while循环来继续循环,直到输入一个有效的数字,并且我们可以使用方法来尝试解析字符串并获得一个整数结果。此方法返回表示成功的Boolean,并接受将设置为整数结果的out参数。
我对您的方法的建议是让它接受一个字符串,该字符串将用作用户的提示符(要求他们输入一个数字),并返回输入的整数结果。
例如:
private static int GetIntFromUser(string prompt, int minValue = int.MinValue,
int maxValue = int.MaxValue)
{
int result;
string errorMsg = $"ERROR: Input must be a valid number from {minValue} to {maxValue}";
while(true)
{
Console.Write(prompt);
string input = Console.ReadLine();
if (!int.TryParse(input, out result) || result < minValue || result > maxValue)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(errorMsg);
Console.ResetColor();
}
else
{
break;
}
}
return result;
}在实践中,我们现在可以调用此方法从用户那里获取数字,并且我们将知道它们是有效的,而无需进行任何额外的验证:
private static void Main()
{
// Age must be between 5 and 100
var age = GetIntFromUser("Please enter your age: ", 5, 100);
// Weight must be a positive number (minimum of zero)
var weight = GetIntFromUser("Please enter your weight: ", 0);
// No restrictions on favorite number
var favNum = GetIntFromUser("Enter your favorite whole number: ");
// This is a similar method I wrote to pause the program with a prompt
GetKeyFromUser("\nDone! Press any key to exit...");
}输出

发布于 2018-08-21 23:15:42
我会这样写(虽然我可能会给用户一个放弃的机会):
private static int GetInput(string v)
{
int intradius = 0; //needs to be initialized to keep compiler happy
while (true)
{
Console.Write($"{v}: ");
string strradius = Console.ReadLine();
if (!int.TryParse(strradius, out intradius))
{
Console.WriteLine($"An integer is required: [{strradius}] is not an integer");
}
else if (intradius < 1)
{
Console.WriteLine($"The entered number [{intradius}] is out of range, it must be one or greater");
}
else
{
break; //breaking out of the while loop, the input is good
}
}
return intradius;
}https://stackoverflow.com/questions/51957673
复制相似问题