リアルタイムキースキャンの甘い罠 §
Consoleクラスの通常の入力メソッドは、通常一度呼び出すと入力があるまで帰ってきません。
しかし、何かの処理を継続しながら【キーが押されたら中断する】という処理を挿入するならそれは困ります。
これに対応するには、Console.KeyAvailable プロパティを使います。
これを参照すると入力済みのキーがあるかを調べることができます。
もし入力があれば、少なくとも1キーは確実に即座に取得できます。
罠の数々 §
- Console.ReadKey メソッドはキーを1つ読み込むが、文字を読み込めるとは限らない。押されたキーはファンクションキーなどの【文字に対応していないキー】かもしれないからだ。
- だから、Console.ReadKey メソッドで返されるのはcharではなくConsoleKeyInfo 構造体である
- ConsoleKeyInfo 構造体からは文字を取り出すことができるが、必ず取り出せるとは限らない
- キー1種類ごとに割り当てられた仮想キーコードは確実に取り出せる。全てのキーに番号の割り当てがあるからだ。
- 仮想キーコードに大文字小文字の区別はない。キーは同じだからだ。だから、小文字のdを打っても取得される仮想キーコードはDに対応したものになる (実行結果参照)
参考リンク §
Console.KeyAvailable プロパティ
Console.ReadKey メソッド
上記のリンクから辿って、ConsoleKeyInfo 構造体の内容を確認しておこう。また、Console.ReadKey メソッドは引数によって入力されたキーを表示する/しないと選択できる。どの引数で制御するか確認しておこう。
リポジトリ §
https://github.com/autumn009/cshowto
RealtimeKeyscan §
using System;
class Program
{
static void Main()
{
for (int i = 0; ; i++)
{
Console.Write($"{i},");
if (Console.KeyAvailable)
{
var key = Console.ReadKey(true);
Console.WriteLine();
Console.WriteLine($"何かのキーが押されました。押されたキーは{key.Key}です。プログラムを中断します。");
break;
}
}
}
}
実行結果(Dキー(通常は小文字のdが入る)を押して止めた結果)
……1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,
何かのキーが押されました。押されたキーはDです。プログラムを中断します。