これが1つのアプローチです。C#は言語のより高度な側面を使用しているため、C#を使い始めたばかりの場合は、おそらくやり過ぎです。いずれにせよ、おもしろいと思います。
それはいくつかの素晴らしい機能を持っています:
ただし、John Wooの回答とは異なり、バックスペースは処理されません。
コードは次のとおりです。
using System;
public static class ConsoleExtensions
{
public static void Main()
{
string entry = ConsoleExtensions.ReadKeys(
s => { StringToDouble(s) /* might throw */; return true; });
double result = StringToDouble(entry);
Console.WriteLine();
Console.WriteLine("Result was {0}", result);
}
public static double StringToDouble(string s)
{
try
{
return double.Parse(s);
}
catch (FormatException)
{
// handle trailing E and +/- signs
return double.Parse(s + '0');
}
// anything else will be thrown as an exception
}
public static string ReadKeys(Predicate<string> check)
{
string valid = string.Empty;
while (true)
{
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
{
return valid;
}
bool isValid = false;
char keyChar = key.KeyChar;
string candidate = valid + keyChar;
try
{
isValid = check(candidate);
}
catch (Exception)
{
// if this raises any sort of exception then the key wasn't valid
// one of the rare cases when catching Exception is reasonable
// (since we really don't care what type it was)
}
if (isValid)
{
Console.Write(keyChar);
valid = candidate;
}
}
}
}
例外をスローする代わりにIsStringOrDouble
戻る関数を実装することもできますが、それは演習として残しておきます。false
これを拡張できるもう1つの方法は、ReadKeys
2つのPredicate<string>
パラメーターを取得することです。1つはサブストリングが有効なエントリーの開始を表すかどうかを判別し、もう1つはそれが完了したかどうかを判別します。このようにして、キーを押すことを許可することはできますが、Enter入力が完了するまでキーを許可しないでください。これは、特定の強度を確保したいパスワード入力や、「はい」/「いいえ」の入力などに役立ちます。