【问题标题】:Two-condition While loop, one of which ends program两个条件 While 循环,其中一个结束程序
【发布时间】:2016-08-03 01:24:12
【问题描述】:

我有一些代码会在用户输入“q”时退出程序

//press 'q' to quit application
ConsoleKeyInfo info = Console.ReadKey(true); ;
while (info.KeyChar != 'q') {
    info = Console.ReadKey(true);
}

如果捕获的键是“p”,我该如何修改这个结构,以便有不同的非终止行为?

如果我将条件更改为:

(info.KeyChar != 'q') && (info.KeyChar != 'p')

那么 'p' 也会终止程序。即使我将逻辑放在 while 循环中来处理“p”的情况。

还有:

ConsoleKeyInfo info = Console.ReadKey(true);
while (true) {
    info = Console.ReadKey(true);
    if (info.KeyChar == 'q') break;
    else if (info.KeyChar == 'p') {
        //other behavior
     }
}

由于某种原因要求用户按两次'q'结束程序,但预期的行为是通过一键触发操作。

【问题讨论】:

  • 查看switch关键字。
  • 我知道 switch 但这将如何解决我的问题?请参阅我的问题末尾的代码
  • 我认为第二种解决方案可以,只需放置 info = Console.ReadKey(true);在 if else 之后,它不应该要求按两次键。
  • 是的,已修复,谢谢

标签: c# while-loop readkey


【解决方案1】:
var exitWhile = false;
while (!exitWhile) {
    ConsoleKeyInfo info = Console.ReadKey(true);
    switch (info.KeyChar) {
        case 'q':
            exitWhile = true;
            break;

        case 'p':
            //something else to do
    }
}

【讨论】:

  • 是的,这更干净,我看到我的问题是在循环之前读取密钥。谢谢
【解决方案2】:

因为你调用了两次 ReadKey,试试这个:

while (true) {
    var info = Console.ReadKey(true);
    if (info.KeyChar == 'q') break;
    else if (info.KeyChar == 'p') {
        //other behavior
    }
}

【讨论】:

  • 就是这样。我在循环之前读取的是第一个输入。非常感谢!
【解决方案3】:

就个人而言,我会选择这样的东西:

ConsoleKeyInfo info;
bool done = false;
while (!done) {
    info = Console.ReadKey(true);
    switch(info.KeyChar) {
        case 'p':
            // do something
            break;
        case 'q':
            done = true;
            // do something else
            break;
    }
}

【讨论】:

  • 是的,这更干净,我看到我的问题是在循环之前读取密钥。谢谢
【解决方案4】:
do {
   info = Console.ReadKey(true);
   if (info.KeyChar == 'q') break;
   else if (info.KeyChar == 'p') {
    //other behavior
   }
}while (true);

【讨论】:

    【解决方案5】:
    ConsoleKeyInfo info = Console.ReadKey(true);
    while (info.KeyChar != 'q') {
        if (info.KeyChar != 'p') {
            // handle p case
        }
        info = Console.ReadKey(true);
    }
    

    【讨论】:

      【解决方案6】:
      while (true)
      {
          ConsoleKeyInfo info = Console.ReadKey(true);
          {
              if (info.KeyChar == 'q')
                  Environment.Exit(0);
              else if (info.KeyChar == 'p')
              {
                  //other behavior
              }
          }
      }
      

      【讨论】:

        【解决方案7】:

        你真的可以用一些更具函数式编程风格的代码来充实你的程序。我假设您想做一些更复杂的事情,而不仅仅是退出,因此我提出了一种模式,对于更基本的场景来说,这将是矫枉过正的。这里的要点是您应该能够用更少的代码指定所有操作,几乎都在一个地方。运行的方法应该是描述性的——几乎是自记录的。

        // Define a class that can return some basic information about what should happen next
        // This only has one property but could be much richer
        public class KeyActionResult {
           public KeyActionResult(bool shouldQuit) {
              ShouldQuit = false;
           }
           public bool ShouldQuit { get; }
           // put other return values or information
        }
        
        public static class MyProgram {
           // Doing this in advance requires the class to be immutable
           private static KeyActionResult _shouldNotQuit = new KeyActionResult(false);
           private static KeyActionResult _shouldQuit = new KeyActionResult(true);
        
           // Work up the vocabulary that you want to be able to use
           private static Action<KeyActionResult> KeepLoopingAfter(Action action) =>
              () => {
                 action();
                 return _shouldNotQuit;
              };
        
           private static Action<KeyActionResult> QuitAfter(Action action) =>
              () => {
                 action();
                 return _shouldQuit;
              };
        
           private Action<KeyActionResult> Quit() => () => _shouldQuit;
        
           private void DoSomethingComplicated() { /* whatever */ }
        

        有了这些,您就可以使用它们来真正清理您的代码了。

           // Bind keys to vocabulary and actions, all in high-signal code
           private static keyActions = new Dictionary<char, Action<KeyActionResult>> {
              ['p'] = KeepLoopingAfter(() =>  Console.WriteLine("You pressed 'p'!")),
              ['d'] = KeepLoopingAfter(DoSomethingComplicated),
              ['q'] = Quit(),
              ['x'] = QuitAfter(() => Console.WriteLine("Delete, then quit!"))
           }
              .AsReadOnly();
        
           // Run the main decision loop
           public static void Main() {
              bool shouldQuit;
              do {
                 ConsoleKeyInfo keyInfo = Console.ReadKey(true);
                 Action action;
                 if (keyActions.TryGetValue(keyInfo.KeyChar, out action)) {
                    shouldQuit = action().ShouldQuit;
                 } else {
                    shouldQuit = false;
                 }
              } while (!shouldQuit)
           }
        }
        

        你可以开始做一些多播来把它提升到一个新的水平......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-15
          • 1970-01-01
          • 1970-01-01
          • 2016-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-08
          相关资源
          最近更新 更多