You could really soup up your program with some code of a more functional programming style. I'm assuming that you want to do some more complex things than just quit, and so am presenting a pattern that would be overkill for more basic scenarios. The gist here is that you should be able to specify all your actions with less code, almost all in one place. And the methods that are run should be descriptive—nearly self-documenting.
// 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 */ }
With that in place, you can use these to really clean up your code.
// 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)
}
}
You could start doing some multicast to take this to the next level...