当我在 .NET Core 3.1 中运行以下代码时,我得到6了返回值。
// .NET Core 3.1
string s = "Hello\r\nworld!";
int idx = s.IndexOf("\n");
Console.WriteLine(idx);
Run Code Online (Sandbox Code Playgroud)
结果:
6
Run Code Online (Sandbox Code Playgroud)
但是当我在 .NET 5.0 中运行这段代码时,我得到了不同的结果。为什么会发生这种情况?
6
Run Code Online (Sandbox Code Playgroud)
结果:
-1
Run Code Online (Sandbox Code Playgroud) 我在尝试将项目从 .NET core 3.1 升级到最新的 .NET 5 时遇到了不兼容的问题。
我的原始代码有一个验证逻辑,通过检查从 Path.GetInvalidFileNameChars() API 返回的每个字符来检查无效的文件名字符。
var invalidFilenameChars = Path.GetInvalidFileNameChars();
bool validFileName = !invalidFilenameChars.Any(ch => fileName.Contains(ch, StringComparison.InvariantCulture));
Run Code Online (Sandbox Code Playgroud)
假设您为 fileName 提供了一个常规值,例如应该有效的“test.txt”。然而,令人惊讶的是,如果您使用“net5”目标框架运行,上面的代码给出的文件名无效。
在调试了一段时间后,我发现返回的无效字符集包含 '\0'、空 ASCII 字符和 "text.txt".Contains("\0, StringComparison.InvariantCulture) 为真。
class Program
{
static void Main(string[] args)
{
var containsNullChar = "test".Contains("\0", StringComparison.InvariantCulture);
Console.WriteLine($"Contains null char {containsNullChar}");
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在 .NET core 3.1 中运行,它永远不会说常规字符串包含空字符。此外,如果我省略第二个参数 (StringComparison.InvariantCulture) 或者如果我使用 StringComparison.Ordinal,则永远不会返回奇怪的结果。
为什么在 .NET5 中改变了这种行为?
编辑: 正如 Karl-Johan Sjögren 之前所评论的,.NET5 中确实存在关于字符串比较的行为变化:
另请参阅相关票证:
string.IndexOf 在 .Net 5 中得到不同的结果
虽然这个问题应该与上面有关,但与 …