与 .NET 6.0 中的 Console.ReadLine() 值混淆。在没有任何其他输入的情况下按 [Enter]

Confused with Console.ReadLine() value in .NET 6.0. while press the [Enter] without any other input

我正在编写一个具有一些基本功能的控制台应用程序,让用户可以输入并根据用户输入做出反应。 在以前的(.net 3.1)中,我可以这样做:

string str=Console.ReadLine();
if(str==""){
     Console.WriteLine("do this");
}
else {
     Console.WriteLine("do that");
}

因为这是一个新的 OS 我只是尝试安装 .net-6.0,没有想太多。 但是,由于 .net-6.0 中的一些更新,Console.ReadLine() 的 return 类型现在是字符串?这是可以为空的,代码将变成如下:

string? str=Console.ReadLine();
if(str==""){
     Console.WriteLine("do this");
}
else {
     Console.WriteLine("do that");
}

因为我想从用户那里得到输入我可以忽略这里的警告使用与.net3.1 相同的编码,string? str=Console.ReadLine() 是否会为 null 并导致 nullreference 异常。或者在什么原因下我可以从 Console.ReadLine();

生成 null

根据 Console.ReadLine 的文档,如果没有更多输入,该方法仅 returns null:

The next line of characters from the input stream, or null if no more lines are available.

尽管如此,无论如何检查一下 null 还是不错的:

string? str=Console.ReadLine();

if (string.IsNullOrEmpty(str))
{
     Console.WriteLine("do this");
}
else
{
     Console.WriteLine("do that");
}

或者,如果您绝对确定不会有 null,只需使用 ! (null-forgiving) operator

Console.ReadLine() returns null 当输入来自管道/重定向的 STDIN(而不是交互式控制台),并且重定向的流到达末尾时;因此,Console.ReadLine() 可以 return null,而且总是可以。

您看到的是一个 c# 8 特性:可为空的引用类型——其中 string? 简单地将其形式化为“我们预计为空的字符串引用”,而不是 string 这意味着“一个永远不应该为空的字符串引用”。这里的关键点是:return 没有改变 - 简单地说:编译器现在认识到 null 是您应该考虑的可能性。

以下程序将获取管道输入,读取到最后,并写入找到的行数:

int count = 0;
while (Console.ReadLine() is not null) count++;
Console.WriteLine(count);

使用时,例如(来自cmd):

MyExe < somefile

然而,当在交互式终端中使用时:它永远不会结束,直到你用 ctrl+c[=20 硬杀死它=]