Als Interface dient eine Console. Der Benutzer soll eine Auswahl treffen. Alles fängt an mit einem If, irgendeinmal wird ein Switch daraus und schlussendlich möchte man dann doch etwas generisches. Bereits unzählige Male habe ich genau für dieses Problem Code geschrieben. Meistens war die Consolen App nur eine kleine Spielerei. Das nächste Mal, am selben Punkt, war der Code nicht mehr auffindbar. Grund genug um hier ein kleines Snippet zu posten.
public class Chooser
{
private const int Offset = 1;
private readonly string question;
private readonly IList<string> options;
public Chooser(string question, IEnumerable<string> options)
{
this.question = question;
this.options = options.ToList();
}
public string AskUser()
{
while (true)
{
Console.WriteLine(question);
Console.WriteLine();
PrintOptionsList();
string answerText = Console.ReadLine();
int answerNumber;
if (int.TryParse(answerText, out answerNumber) && answerNumber - Offset < options.Count && answerNumber - Offset >= 0)
{
Console.Clear();
return options[answerNumber - Offset];
}
Console.Clear();
}
}
private void PrintOptionsList()
{
for (int i = 0; i < options.Count; i++)
{
var option = options[i];
Console.WriteLine("{0}. {1}", i + Offset, option);
}
}
Und hier noch die Enhanced Version:
public class Chooser<TAnswer>
{
private const int Offset = 1;
private readonly string question;
private readonly IEnumerable<KeyValuePair<string, TAnswer>> options;
public Chooser(string question, IEnumerable<KeyValuePair<string, TAnswer>> options)
{
this.question = question;
this.options = options;
}
public TAnswer AskUserAcceptSingleAnswer()
{
return AskUser("").Single();
}
public IEnumerable<TAnswer> AskUserAcceptMultipleAnswers()
{
return AskUser(",");
}
public IEnumerable<TAnswer> AskUserAcceptMultipleAnswers(string separator)
{
return AskUser(separator);
}
private IEnumerable<TAnswer> AskUser(string separator)
{
while (true)
{
Console.WriteLine(question);
Console.WriteLine();
PrintOptionsList();
string answerText = Console.ReadLine();
foreach (var splittedAnswerText in answerText.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries))
{
int answerNumber;
if (int.TryParse(splittedAnswerText, out answerNumber) && answerNumber - Offset < options.Count() && answerNumber - Offset >= 0)
{
Console.Clear();
yield return options.ElementAt(answerNumber - Offset).Value;
}
Console.Clear();
}
}
}
private void PrintOptionsList()
{
for (int i = 0; i < options.Count(); i++)
{
var option = options.ElementAt(i).Key;
Console.WriteLine("{0}. {1}", i + Offset, option);
}
}
}