Runtime: String.StartsWith() fails to return cases which end with string "NJ", when using StartsWith("N")

Created on 21 Feb 2020  路  10Comments  路  Source: dotnet/runtime

I've tested this both on .Net and .Net Core and the bug is persistent.
Example:

List<string> list = new List<string>(); for (int i = 0; i < 10; i++) { list.Add("NJ"); } var result= list.Where(x => x.StartsWith("N"));

// result returns 0 elements.
// If you change "NJ" in the list to any other combination with 'N', for example "NQ",
// result returns 10 elements.

It's not just capital "NJ". This doesn't work even if the list is filled with "nj" and the StartsWith() has predicate "n".

At first I was dealing with a longer strings which I was deserializing from JSON and then filtering by predicate "lblPON" (the strings were of format "lblPON" + letter from alphabet). And when I got to case where string is equal to "lblPONJ" and my StartsWith() predicate is "lblPON", it would simply skip it. I've lost a couple hours on this since at first I thought the problem was in my JSON file but I finally managed to narrow it down.

untriaged

All 10 comments

I just tested using your code above on netcore 3.1 and I get the result count expected correctly. Can you confirm that you've tried it on 3.1, identify the os (windows and unix use different localization libraries) and provide the value of CultureInfo.CurrentCulture.Name in case it's related to localization in that culture.

Hi Wraith, just tested it on netcore 3.1 (was on 3.0 previously), and it still fetches 0 items with Where()
I'm on windows with CultureInfo.CurrentCulture.Name = hr-HR

Now that you mention localization in the culture... Croatian language _does_ have a letter "Nj". Maybe it is because of that? Any way to escape the localization?

List<string> list = new List<string>();
            for (int i = 0; i < 10; i++)
            {
                list.Add("D沤");
            }
            var result = list.Where(x => x.StartsWith("D"));

Update: just tested the case above. It really doesn't work for this case as well as 'D啪' is a letter in Croatian language. Thanks for suggesting the problem lay in my culture's localization.

Anyway, for people running into this problem.
All I did was set
CultureInfo.DefaultThreadCurrentCulture to CultureInfo.InvariantCulture;

There should be an overload of StartWith which takes a StringComparison enum member as a parameter which would let you pass in the Ordinal or InvariantCulture options for this comparison, using it would be less invasive than forcing the current thread into a different culture.

There should be an overload of StartWith which takes a StringComparison enum member as a parameter

There is:
https://docs.microsoft.com/en-us/dotnet/api/system.string.startswith?view=netcore-3.1#System_String_StartsWith_System_String_System_StringComparison_

@Wraith2 Thanks, I switched to StartsWith(nameFilter, StringComparison.InvariantCulture)

There is:

I know 馃榾 , it's British polite idiom, "there should be a" -> "if you look you will you will find that there is"

:smile:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamesqo picture jamesqo  路  3Comments

aggieben picture aggieben  路  3Comments

matty-hall picture matty-hall  路  3Comments

btecu picture btecu  路  3Comments

noahfalk picture noahfalk  路  3Comments