我想学习如何实现int。在我的代码中尝试parse命令,以防止程序因无效输入而崩溃。这是我目前为止写的内容:
using System;
namespace barn_
{
class Program
{
static void Main(string[] args)
{
int age;
string a;
do
{
Console.WriteLine("How old is the person?");
age = Convert.ToInt32(Console.ReadLine());
a = Convert.ToString(Console.ReadLine());
bool v = int.TryParse(a, out age);
while(a == true)
{
Console.WriteLine("");
Console.WriteLine("");
}
if (age >= 2 && age <= 5)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("The person has blue clothes.");
}
else if (age >= 6 && age <= 9 || age >= 10 && age <= 15)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("The person has red clothes.");
}
else if (age < 2)
{
Console.WriteLine("The person is too young.");
Console.WriteLine();
}
else if (age > 15)
{
Console.WriteLine("The person is too old.");
Console.WriteLine();
}
} while (age < 2 || age > 15);
}
}
}
您可以提取一个方法来读取整数值:
private static int ReadInteger(string title, int from, int to) {
// Keep asking user until some valid input is provided
while (true) {
// If we have a title, print it
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
// First we try to parse user input
if (int.TryParse(Console.ReadLine(), out int result))
// if parsing succeeds, check for ranges
if (result >= from && result <= to)
return result; // result is a valid value in [from..to] range
else // valid integer, but out of [from..to] range, say, 12345 or -97
Console.WriteLine($"Value is out of [{from}..{to}] range. Please, try again.");
else // not a valid integer, say, "bla-bla-bla"
Console.WriteLine("Not a valid integer value. Please, try again.");
}
}
那么你可以这样使用这个方法:
static void Main(string[] args) {
// we read and integer, say, in [0..122] range
// https://en.wikipedia.org/wiki/Jeanne_Calment
int age = ReadInteger("How old is the person?", 0, 122);
// try to order the conditions: when ordered they are more readable
if (age < 2)
Console.WriteLine("The person is too young.");
else if (age <= 5) {
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("The person has blue clothes.");
}
else if (age <= 15) {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("The person has red clothes.");
}
else
Console.WriteLine("The person is too old.");
}
以下是我的回答,我将尽量避免可能的坏习惯。对于大多数用例来说,我的代码示例可能有些夸张,但是我想澄清几点,并解释面向对象编程中的可重用性方面。然而,@Dmitry Bychenko的回答和对你问题的评论高度肯定地解决了你所描述的问题。
根据您正在开发的IDE(例如Visual Studio 2019),记录良好的方法,这是大多数系统方法(如int.TryParse
或Convert.ToInt32
)的情况,将向您显示可能发生的异常。例如,对于int.TryParse
,如果没有输入整数,则不会抛出异常。这与Convert.ToInt32
不同。如果您尝试用Convert.ToInt32
转换非整数字符串,则抛出异常FormatException
,表明要转换的部分不是整数。
现在到代码示例和可重用性。示例的下面两个代码片段非常相似。这主要可以从可以从中生成方法的事实中推断出来。在Visual Studio 2019中,可以使用"Ctrl + R + M"创建自动生成的方法。
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("The person has blue clothes.");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("The person has red clothes.");
在后面的代码示例中,这个方法的名称是"PrintTextInConsoleInColor"使用方法的一个很好的理由是设置了颜色并打印了文本。这种模式不断重复。如果你想在每次设置颜色时输出声音,你就必须改变代码出现的每个部分。这是非常糟糕的,需要付出很多努力,甚至不一致。对于大型项目来说,这是非常严重和耗时的,当然,对于比设置颜色和播放声音更复杂的过程来说,这只是一个演示。
方法的命名也起着重要的作用。我们必须考虑到这不仅仅是主机输入。这就是GetIntegerFromConsoleInput"在纯控制台应用程序的上下文中被夸大了,尽管从方法的名称中应该总是清楚地知道内部或调用它时发生了什么,以便在执行它时您不会突然感到惊讶。
在可重用性方面,将您想要的逻辑分成几个部分是有意义的,例如"getintegerfromconsoleinput";和";GetIntegerInRangeFromConsoleInput"。这样做的原因是,如果你只需要一个数字,方法"getintegerfromconsoleinput";可以使用。然而,如果你需要一个范围内的数字,就像你的情况一样,getintegerinrangefromconsoleinput;将被使用。如果您现在查看该方法的文档,您可以看到异常的文档,它也由像visualstudio"这样的IDE应用。基本上,还建议避免嵌套&;if语句&;和"循环",因为这会严重影响代码的可读性。在控制台中,可以通过控制字符插入空行,这样可以节省多次使用"Console. writeline (")"
。Console.WriteLine("HellonWorld");
最后,一个为ConsoleIO编写类以及如何重用它的潜在解决方案。
public class ConsoleIOHelper
{
/// <summary>
/// Get console input within range.
/// </summary>
/// <param name="lowerBoundary"> Lower boundary included in Range.</param>
/// <param name="upperBoundary"> Upper boundary included in Range.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown in case the lower boundary is greater than the upper boundary.</exception>
public int GetIntegerInRangeFromConsoleInput(int lowerBoundary, int upperBoundary)
{
if (lowerBoundary >= upperBoundary)
{
throw new ArgumentOutOfRangeException(nameof(lowerBoundary), "Lower boundary has to be lower than upper boundary!");
}
int result;
bool isInRange;
do
{
result = GetIntegerFromConsoleInput();
isInRange = IsInBoundaries(result, lowerBoundary, upperBoundary);
if (!isInRange)
{
PrintTextInConsoleInColor($"Input {result} is not within boundaries of {lowerBoundary} and {upperBoundary}", ConsoleColor.Red);
}
}
while (!isInRange);
return result;
}
/// <summary>
/// Get interger from console input.
/// </summary>
public int GetIntegerFromConsoleInput()
{
bool isInteger;
int result;
do
{
isInteger = int.TryParse(Console.ReadLine(), out result);
if (!isInteger)
{
PrintTextInConsoleInColor("Input is not a number!", ConsoleColor.Red);
}
}
while (!isInteger);
return result;
}
/// <summary>
/// Checks weather a input number is within lower and upper boundary.
/// </summary>
private bool IsInBoundaries(int input, int lowerBoundary, int upperBoundary)
{
return input >= lowerBoundary && input <= upperBoundary;
}
private void PrintTextInConsoleInColor(string message, ConsoleColor consoleColor)
{
Console.ForegroundColor = consoleColor;
Console.WriteLine(message);
Console.ResetColor();
}
}
我希望我能使你的问题更清楚,即使我已经大大偏离了实际问题。如果我描述了一些大家已经知道的事情,我很抱歉,我只是想用这个例子来指出一些让我震惊的事情。