5

I have the following line of code:

String.Equals("strasse", "straße", StringComparison.InvariantCultureIgnoreCase)

In .net 4.7.2, this returns true.
In .net 5 (and .net 6), this returns false.

Why?


I'm currently learning how comparing strings works in C#. NET. and have come across an unexpected result that I do not fully understand.

When using the overloaded method String.Equals(string,string,Stringcomparison) to compare string :"strasse" and string : "straße" with the following Stringcomparison :

Console.WriteLine(String.Equals("strasse", "straße", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(String.Equals("strasse", "straße", StringComparison.CurrentCultureIgnoreCase));
Console.WriteLine(String.Equals("strasse", "straße", StringComparison.InvariantCultureIgnoreCase));

I get the following result :

False 
False
False

I expected the first one to return false but both the second and third line to return true. I first though maybe my CurrentCulture was the issue, so to be sure is et both the CurrentCulture and CurrentUICulture to :

CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("de-DE");
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");

Did I incorrectly understand String comparison ? or am I missing something obvious here ?

Thanks in advance for anyone willing to help me understand

gunr2171
  • 16,104
  • 25
  • 61
  • 88
M-JM
  • 93
  • 6
  • Even without setting current culture, I just ran `Console.WriteLine(String.Equals("strasse", "straße", StringComparison.InvariantCultureIgnoreCase));` and it printed `True` – Bugbeeb Dec 14 '21 at 01:58
  • `CurrentCulture` results will depend on what the thread's culture is set to – Bugbeeb Dec 14 '21 at 01:59
  • @Bugbeeb Shouldn't `InvariantCultureIgnoreCase` comparison have given me `True` regardless of what my CurrentCulture would have been set to ? – M-JM Dec 14 '21 at 02:09
  • 1
    Turns out that if we target framework 5.0 and above it does not give the result I expected. However I just made a new Console App with .NET framework 4.7.2 and got the exact result I was expecting. I looked at the changes of .NET 5 and could not find something that would explain the difference. Could anyone point me in the right direction on this ? – M-JM Dec 14 '21 at 02:29
  • I was running .Net Core 3.1, interesting that this changed in .Net 5... – Bugbeeb Dec 14 '21 at 02:39
  • 6
    https://learn.microsoft.com/en-us/dotnet/core/compatibility/globalization/5.0/icu-globalization-api – Hans Passant Dec 14 '21 at 03:08
  • Did you try also set: `CurrentCulture and CurrentUICulture` – Charles Dec 14 '21 at 07:34
  • @HansPassant I checked the changes and if I understood it correctly , the fact they switched over to the ICU api for globalization should be the cause of the change. When looking around at the ICU documentation , I came across this https://icu4c-demos.unicode.org/icu-bin/scompare and entered the strings in their comparer. It returned that it is indeed equivalent-caseless. So why does this not reflect the same in c# ? – M-JM Dec 15 '21 at 14:50

1 Answers1

2

When you target .NET Framework 4.x you are implicitly targeting a Windows Platform. Windows platforms handle Unicode and Cultures in their specific way, which is the direct byproduct of the evolution of the platform during the last 30 years. The standard for Windows platforms is using NLS Apis.

However, this is not the case for other platforms.

During the past years the ICU project tried to provide a unified, de-facto standard for handling Unicode characters (and more). Since .NET Core runs by design on Windows, Linux, Mac and (possibly) Android devices, you expect your application to behave consistently regardless the platform it runs on

For this reason, .Net Core 5 switched to ICU libraries as a breaking change. You can find more information on Globalization APIs use ICU libraries on Windows. ICU libraries are available for many languages and are interoperable, thus allowing better integration.

Yennefer
  • 5,704
  • 7
  • 31
  • 44