Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent string.StartsWith on different platforms

Tags:

c#

.net-core

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://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)}");
    }

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

like image 466
wmz Avatar asked Sep 18 '18 22:09

wmz


People also ask

How to check StartsWith in c#?

C# | StartsWith() Method. In C#, StartsWith() is a string method. This method is used to check whether the beginning of the current string instance matches with a specified string or not. If it matches then it returns the string otherwise false.

Is StartsWith in C# case sensitive?

The StartsWith method is called several times using case sensitivity, case insensitivity, and different cultures that influence the results of the search.

How do you check if a string starts with another string?

The startsWith() method returns true if a string starts with a specified string. Otherwise it returns false . The startsWith() method is case sensitive.


1 Answers

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

like image 126
jazzdelightsme Avatar answered Nov 15 '22 11:11

jazzdelightsme