在任何输入过程中随时退出控制台应用程序(C#)

在任何输入过程中随时退出控制台应用程序(C#),c#,C#,我有一个相对较大的控制台应用程序,有多个菜单和用户输入。我需要为用户创建一种随时“退出”或“返回”的方式,本质上是break当前正在进行的方法。我考虑过使用一大堆条件句,但这需要一些时间,而且不是很干净。有没有办法持续检查“Q”退出并在整个项目中运行基于该输入的方法 伪代码 我现在所拥有的: UserInput #1; UserInput #2; UserInput #3; //ETC.... PromptFor Quit; //Option to quit after inputs are

我有一个相对较大的控制台应用程序,有多个菜单和用户输入。我需要为用户创建一种随时“退出”或“返回”的方式,本质上是
break当前正在进行的方法。我考虑过使用一大堆条件句,但这需要一些时间,而且不是很干净。有没有办法持续检查“Q”退出并在整个项目中运行基于该输入的方法

伪代码


我现在所拥有的:

UserInput #1;
UserInput #2;
UserInput #3; //ETC....
PromptFor Quit; //Option to quit after inputs are completed.
我想尝试的是:

UserInput #1;
PromptFor Quit#1; //Add prompt to quit after every input as a conditional.
UserInput #2; 
PromptFor Quit#2;
UserInput #3;
PromptFor Quit#3;
我想要的是:

PromptForQuit    //Some method of constantly checking if userInput hit's "Q" or "ESC" key is entered.
    {
      UserInput#1;
      UserInput#2;
      UserInput#3; // etc..
    }

我可以通过将它硬编码到每一个方法中来解决它,但必须有更好的方法。另外,我需要向控制台输出,对于每个输入,都有一个“Q”退出选项

简单回答:只要使用
ctrl+C
随时退出控制台(无需代码)

如果您想在存在之前执行一些清理操作:那么您可能正在寻找


您可以找到相关答案。

简单答案:只需使用
ctrl+C
随时退出控制台(无需代码)

如果您想在存在之前执行一些清理操作:那么您可能正在寻找


你可以找到相关的答案。

从90年代初开始,我就没有做过复杂的控制台应用程序。如果我有一个“具有多个菜单和用户输入”的应用程序,我通常使用一些本机支持的东西(Windows窗体、WPF、web应用程序)。但是

如果这是一个足够大/复杂的项目,特别是如果您计划编写多个项目,那么基于模型-视图-控制器(MVC)模式编写一个小框架可能是值得的

在本例中,我们实际上有两个模型,一个是描述程序流程的相当复杂的模型,另一个是包含用户答案的简单
字典。控制器是一个简单的处理循环,它执行第一个模型中的指令。视图非常简单,但我们将看到,通过将其分离出来,有一些优势

要做到这一点,您需要完全改变编程的结构。我假设它主要是这样的:

 Console.WriteLine("UserInput #1");
 var response = Console.ReadLine();
 DoSomethingWith(response);
 Console.WriteLine("UserInput #2");
 response = Console.ReadLine();
 DoSomethingWith(response);
 // lather, rinse, repeat
相反,程序的流程将由第一个模型决定。所以

模型 第一个模型是重要的部分,但是让我们先把第二个模型放在一边。第二个模型(AnswerModel)只是一个
列表
,其中
答案
类似于:

public class Answer {
    public string StepName { get; set; }
    public string VerbatimResponse { get; set; }
    public object TypedResponse { get; set; }
    public Type ResponseType { get; set; }
}
public enum UserInputType {
    String,
    Integer,
    Numeric,
    Enum,
}
public interface IConsoleView {
    void Write(string stringToWrite);
    void WriteLine(string stringToWrite);
    string ReadLine(string prompt);
}
它代表了一个特定问题的答案。答案列表表示到目前为止用户所有问题的答案。也许可以玩一些泛型游戏(可能是继承),使
TypedResponse
属性实际上正确键入,这应该足以让我们开始

第一个模型,输入模型是程序的核心。它将由
ModelStep
对象的集合组成。集合可以是一个简单的列表(问题1、问题2等),也可以是一个复杂的图形。特别是,下面显示的模型中的
EvalNextStep
delegate属性允许您构建一个简单的状态机(例如,如果您的问题之一是“您的性别是什么?”,则可以为男性和女性提供一个单独的路径)

InputModel看起来像这样(您可以根据自己的需要进行调整):

这两个验证器用于验证用户输入。
TypeValidator
类很可能是
abstract
,具有如下具体子类:

  • StringValidator
  • IntegerValidator
  • DoubleValidator
  • EnumValidator,其中T:enum
在live中,TypeValidator的角色是接受用户的输入,验证它是否为正确的类型,然后返回错误消息或作为正确类型对象的响应

SpecificValidator
对象将执行附加验证
SpecificValidator
也可能是一个
抽象类,具有以下具体子类:

  • lessthan验证程序,其中T:i可比较
  • GreaterThanValidator,其中T:i可比较
  • rangnevaluator,其中T:IComparable
AdditionalValidator
属性是可选的。如果需要,它将提供额外的验证。如果验证失败,它将返回一条错误消息

AfterInputAction
委托可以选择性地指向一个函数,该函数接受到目前为止的所有答案和当前步骤名称,并在需要时使用该信息执行某些操作

EvalNextStep
委托将接受与
AfterInputAction
委托相同的输入,并返回“下一步”运行。如上所述,这将允许您创建一个简单的“状态机”。你可能不需要这个,但它可以让它变得有趣

控制器 控制器是程序的核心,但它非常简单。在程序开始时,您会将InputModel和指示第一步的东西交给控制器,控制器只需遍历InputModel集合,提示用户并请求响应

然而,由于所有用户交互都在一个地方,所以实现“退出”功能将很容易。您还可以实现其他类似功能,如:

  • 返回(返回上一个问题并查看您的答案。您可以构建“返回堆栈”,并允许用户在需要时多次返回)
  • 前进(如果有人使用“后退”,则允许他们前进-可能使用“前进堆栈”)
  • 跳过(如果问题是可选的,用户可以跳过)

public enum UserInputType { String, Integer, Numeric, Enum, }

public interface IConsoleView {
    void Write(string stringToWrite);
    void WriteLine(string stringToWrite);
    string ReadLine(string prompt);
}
void WriteStepName(string stepName);
void WriteUserResponse (string userResponse);