向用户索取数据 - Spectre 控制台系列
C# 控制台应用程序一直是学习程序如何读取用户输入并显示输出的最简单方法。 在他的 Spectre.Console 系列中,Tim Corey 展示了如何远远超越普通的黑白命令提示符。 在本文中,我们将仔细观察他的视频"从用户处请求数据 - Spectre 控制台系列",看看他是如何收集输入、处理数值、进行错误检查并为程序赋予更友好的外观的,而这一切都无需手动修改模板代码。 视频中包含时间戳,您可以跳转到正确的位置。
简介:命令行输入变得更简单
一开始,蒂姆就提醒我们,Spectre.Console 可以将普通的 C# 命令行输入转化为具有视觉吸引力的内容。 无需编写完整的 static void Main(string[] args) 方法,然后使用 Console.ReadLine() 手动从标准输入流中读取数据、解析数据并处理异常,Spectre.Console 会为您完成这些工作。
用蒂姆的话说(0:17),本课将展示如何 "要求用户输入、验证数据并将其转换为适当的数据类型"--这是任何使用控制台或命令提示符的开发人员的核心技能。
使用 Ask 读取整数值
Tim 的第一个例子(0:35)是大家都很熟悉的:询问用户的年龄。 传统上,您可以用 C# 来编写:
static void Main(string[] args)
{
Console.Write("Enter integer age: ");
string input = Console.ReadLine();
int age = int.Parse(input);
}static void Main(string[] args)
{
Console.Write("Enter integer age: ");
string input = Console.ReadLine();
int age = int.Parse(input);
}这显示了 C# 程序的经典入口点、主函数,以及如何通过控制台从键盘接收输入参数。 您还必须使用 int.Parse 或 Convert.ToInt32 将输入的字符串转换为 int 年龄。 Tim 指出,您必须自己处理无效输入并抛出或捕获异常。
对于 Spectre.Console,他只需简单地编写即可:
int age = AnsiConsole.Ask<int>("What is your age?");int age = AnsiConsole.Ask<int>("What is your age?");这一行会读取输入内容,将其转换为整数值,如果用户输入的是非数字字符,则会显示红色错误信息--无需额外的错误检查代码。 当用户按下 Enter 键时,该方法会读取输入内容,将其解析为数字类型,并存储到年龄变量中。
布尔输入以及为什么 Prompt 更好
下一步 (1:14) Tim 演示询问布尔值:
bool isHappy = AnsiConsole.Ask<bool>("Are you happy?");bool isHappy = AnsiConsole.Ask<bool>("Are you happy?");如果用户输入 "true "或 "false",它就会工作。 但如果他们输入 "是",Spectre.Console 就会显示红色错误。 这表明,虽然 Ask

这时,Tim 转而使用更灵活的 API - Prompt,它的行为更像是一个可以自定义的迷你类。
使用 TextPrompt 提供选择
3:02 时,Tim 使用 TextPrompt
var happyText = AnsiConsole.Prompt(
new TextPrompt<string>("Are you happy?")
.AddChoice("Yes")
.AddChoice("No"));var happyText = AnsiConsole.Prompt(
new TextPrompt<string>("Are you happy?")
.AddChoice("Yes")
.AddChoice("No"));程序执行时(4:48),控制台会在问题后显示([是/否/])。 这是 Spectre.Console 在命令行中的装饰,用户可以轻松看到可接受的答案。 如果您输入了其他内容,该方法会接收并与列表进行核对,然后显示一条友好的消息,告诉您选择一个可用的选项。

添加默认值
然后,Tim 添加了一个默认值(5:16):
.DefaultValue("Yes").DefaultValue("Yes")现在,当程序运行时,用户只需按回车键(没有文本的回车键),该方法就会自动将 "是 "赋值给变量。 当您想在主方法中存储一个合理的默认值而不需要额外的代码时,这就非常好。
通过验证提示整数
6:01 时,Tim 展示了一个更丰富的示例,其中包含整数输入。 他使用一个新的 TextPrompt 再次询问年龄,但在提示中加入了验证逻辑:
int age = AnsiConsole.Prompt(
new TextPrompt<int>("What is your age?")
.Validate(x =>
{
return x switch
{
< 0 => ValidationResult.Error("[red]You were not born yet[/]"),
> 120 => ValidationResult.Error("[red]You are too old[/]"),
_ => ValidationResult.Success(),
};
}));int age = AnsiConsole.Prompt(
new TextPrompt<int>("What is your age?")
.Validate(x =>
{
return x switch
{
< 0 => ValidationResult.Error("[red]You were not born yet[/]"),
> 120 => ValidationResult.Error("[red]You are too old[/]"),
_ => ValidationResult.Success(),
};
}));在这里,提示符不仅要将标准输入流中的字符串值转换为数字类型,还要根据业务规则执行错误检查,例如不允许使用负年龄。 蒂姆现场测试(8:31):输入 -1 会触发 "你还没出生"。输入 150 会触发 "你太老了"。只有有效输入才能让程序继续下一行。

这种内置验证功能消除了在主函数中手动编写 if 语句、调用解析方法和处理异常的需要。
询问与提示:何时分别使用这两种工具
9:00 时,Tim 总结道:
Ask:快速简单。 当您的程序只需要读取一个输入参数并将其转换为已知类型时,就非常完美了。
- 提示:功能更强大。 让您添加选择、默认值和验证。 在您构建更丰富的控制台应用程序或与其他使用命令行参数调用您的可执行文件的程序进行集成时,它将是您的得力助手。
这两种方法仍然可以很好地融入到您的 static void Main(string[] args) 甚至 public static void Main(string[] args) 入口点中。 您还可以访问 args 读取程序执行时传递的命令行参数,将其与 Spectre.Console 提示相结合,并使用 string.Format 或插值法输出格式整齐的字符串。
为什么这对控制台开发人员很重要
最后(9:19),Tim 指出这种方法如何 "将征求用户输入的能力提升到一个新的水平"。有了 Spectre.Console,你不再需要编写重复的代码来读取键盘输入、使用转换类进行转换并显示默认信息。 您将得到
在命令提示符下提供丰富的彩色输出。
自动解析数字类型、双数值或字符串值。
对无效输入进行友好的错误处理。
- 能够将提示与传统命令行参数相结合,以实现混合输入模式。
这样,在向初学者传授主要方法、数据类型和输入参数的同时,还能在 Visual Studio 或其他任何编辑器中编写专业级的控制台应用程序,从而使初学者更容易掌握。
结论
通过观看 Tim Corey 在视频中的演示,您可以了解到:
如何使用 Spectre.Console 的 Ask 读取和转换用户输入。
如何使用 TextPrompt 提供选择、默认值和验证。
这些提示如何与命令行参数一起自然地融入 Main(string[] args) 入口点。
- 如何减少模板式错误检查并使您的命令行应用程序更友好。
Tim 展示的所有内容仍可编译成单个可执行文件,您可以通过命令提示符运行、传递参数或嵌入到更大的 Windows 窗体应用程序或工具中。 这是一种处理用户输入的现代方式,同时保持 C# 控制台的简洁性及其熟悉的主功能。

