调用Console.ReadKey()
并在提示符处对长度 > 1 的任何剪贴板文本进行粘贴(编辑->粘贴)(比如说“Hello World!”)。
我刚刚意外地发现,在随后调用 Console.ReadKey() 时,向用户显示提示,却没有给出提示!相反,粘贴文本中的后续字符会被读取......没有提示!
底线:要使用 ReadKey,我需要确保(非常确定)当我下次调用 ReadKey 时,它实际上会给用户一个提示。目前,这使得 ReadKey 无法用于此类关键场景。
看起来没有任何方法可以禁用此功能,或者只是清除输入但尚未读出的值。
就我而言,这在简单的控制台应用程序中出现了严重错误,我在其中循环寻找“RUN”的单词“R”或任何“E”到“END”。由于接近这个时间,我提示输入文件路径,因此对于已经使用它的用户来说,在这一点上意外粘贴文件路径是相当容易的。问题是(!!!),如果该文件路径包含“r”,它会立即运行。
using System;
namespace Practise1
{
class Program
{
static void Main()
{
RunDialogue2();
}
public static void RunDialogue()
{
while (true) {
Console.WriteLine("Type 'R' to RUN, 'E' to END");
ConsoleKey key = Console.ReadKey().Key;
Console.WriteLine("\r\n");
switch (key) {
case ConsoleKey.R:
Console.WriteLine("RUN! ENGINES BLAST OFF!");
BlastOff();
break;
case ConsoleKey.E:
Console.WriteLine("FINISHED");
return;
default:
Console.WriteLine("INVALID ENTRY, TRY AGAIN");
// we *thought* this would pick up bad input, but not pasted text!
break;
}
}
}
public static void RunDialogue2()
{
while (true) {
Console.WriteLine("Type 'R' to RUN, 'E' to END");
ConsoleKey key = Console.ReadKey().Key;
Console.WriteLine("\r\n");
switch (key) {
case ConsoleKey.R:
Console.WriteLine("RUN! ENGINES BLAST OFF!");
Console.WriteLine("We blasted off at: " + DateTime.UtcNow);
//BlastOff();
break;
case ConsoleKey.E:
Console.WriteLine("FINISHED");
return;
default:
Console.WriteLine("INVALID ENTRY, TRY AGAIN");
// we *thought* this would pick up bad input, but not pasted text!
break;
}
}
}
}
}
如果你有“查理的!” 在剪贴板中并粘贴它,这是输出。请注意如何获得多个 RUN!都是无意的。非常可怕,这有多糟糕,这对我来说意味着我们永远不能依赖 ReadKey 作为一种可靠的输入方法,特别是当我们认为我们正在验证输入时:
Type 'R' to RUN, 'E' to END
C
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
h
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
a
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
r
RUN! ENGINES BLAST OFF!
We blasted off at: 7/21/2013 11:24:36 PM
Type 'R' to RUN, 'E' to END
l
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
e
FINISHED
我知道一个解决方案是改用 Console.ReadLine,但是通过单次按键立即交互的能力要快乐得多。有什么办法可以解决这种奇怪的行为吗?