wmz
wmz

Reputation: 3685

Inconsistent string.StartsWith on different platforms

Given documentation for string.StartsWith and this snippet (targeting .net core 2.x):

This method compares the value parameter to the substring at the beginning of this string that is the same length as value, and returns a value that indicates whether they are equal. To be equal, value must be an empty string (String.Empty), must be a reference to this same instance, or must match the beginning of this instance. This method performs a comparison using the specified casing and culture.
https://learn.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)}");
    }

It produces expected result on Windows:

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

but when run on Linux (via docker) the result is:

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

Would you consider this a bug?
Platform dependent behavior?

Please note I'm not asking how to make it work (change to str.StartsWith(unicodeCtrl,StringComparison.OrdinalIgnoreCase)) but rather if you believe this is intended/correct behavior.

Edit: I tried to match my local locale on Linux, but it did not make a difference. I tried default C (en-US-POSIX) and pl_PL.UTF8

Upvotes: 8

Views: 808

Answers (1)

jazzdelightsme
jazzdelightsme

Reputation: 477

This is a known difference between Windows and Linux/Unix: on Unix platforms, nulls have no "weight". The behavior of .NET here is By Design, to match platform expectations, rather than to provide consistency. If you want the nulls to "count", you'll have to use an ordinal comparison.

See here: https://github.com/dotnet/coreclr/issues/2051#issuecomment-277005422

And here: https://github.com/dotnet/corefx/pull/29935/files#diff-91724393075e1a7718d3521655506742R1399

Upvotes: 5

Related Questions