字符串不一致。StartsWith在不同平台上

时间:2018-09-18 22:36:23

标签: c# .net-core

给出string.StartsWith和此代码段的文档(针对.net core 2.x):

  

此方法将value参数与该字符串开头的子字符串进行比较,该子字符串的长度与value相同,并返回一个指示它们是否相等的值。为了相等,value必须是一个空字符串(String.Empty),必须是对该相同实例的引用,或者必须与该实例的开头匹配。   此方法使用指定的大小写和区域性进行比较。
  https://docs.microsoft.com/en-us/dotnet/api/system.string.startswith?view=netcore-2.1

static void Main(string[] args)
    {
        var unicodeCtrl = "\u0000";
        var str = "x";
        Console.WriteLine($"Is it empty     => {unicodeCtrl == string.Empty}");
        Console.WriteLine($"Lenghts         => {str.Length} {unicodeCtrl.Length}");
        Console.WriteLine($"Are they equal  => {str == unicodeCtrl}");
        Console.WriteLine($"Are they ref eq => {Object.ReferenceEquals(str, unicodeCtrl)}");
        Console.WriteLine($"Contains        => {str.Contains(unicodeCtrl)}");
        Console.WriteLine($"Starts with     => {str.StartsWith(unicodeCtrl)}");
    }

它在Windows上产生预期的结果:

Is it empty     => False  
Lenghts         => 1 1
Are they equal  => False  
Are they ref eq => False  
Contains        => False  
Starts with     => False

但是在Linux上(通过docker)运行时,结果是:

Is it empty     => False
Lenghts         => 1 1
Are they equal  => False
Are they ref eq => False
Contains        => False
Starts with     => True

您认为这是一个错误吗?
平台相关的行为?

请注意,我并不是在问如何使它工作(更改为str.StartsWith(unicodeCtrl,StringComparison.OrdinalIgnoreCase)) 而是如果您认为这是故意的/正确的行为。

编辑:我试图在Linux上匹配我的本地语言环境,但没有任何区别。我尝试了默认的C(en-US-POSIX)和pl_PL.UTF8

1 个答案:

答案 0 :(得分:5)

这是Windows与Linux / Unix之间的已知区别:在Unix平台上,空值没有“权重”。 .NET的行为是设计使然,以符合平台的期望,而不是提供一致性。如果要让空值“计数”,则必须使用序数比较。

参见此处:https://github.com/dotnet/coreclr/issues/2051#issuecomment-277005422

在这里:https://github.com/dotnet/corefx/pull/29935/files#diff-91724393075e1a7718d3521655506742R1399