| Method | Mean | Error | StdDev |
|--------------- |----------:|---------:|---------:|
| IndexOfOrdinal | 47.71 ns | 0.963 ns | 2.344 ns |
| IndexOfDefault | 201.93 ns | 3.893 ns | 4.923 ns |
| Method | Mean | Error | StdDev |
|--------------- |----------:|---------:|---------:|
| IndexOfOrdinal | 47.71 ns | 0.963 ns | 2.344 ns |
| IndexOfDefault | 201.93 ns | 3.893 ns | 4.923 ns |
A non-ordinal string comparison may take into account other things such as iterating by actual characters and comparing them in language and culture-aware ways. This is useful for ordering things by name when showing a list to users.
It's not the same for all versions of German though. For example in Swiss German ß is not used and is replaced by "ss".
I do not know about Austrian German but I would not be surprised if they have some specificities around the letter ß.
In short: it's complicated :)
(Also, I should've said codeunit-compare instead of byte-compare, since C# strings are always UTF-16 encoded).
But ordinal comparison means ignoring equivalence classes, like U+006E (n) + U+0303 (combining tilde) being considered the same as U+00F1 (ñ). But - perhaps more surprisingly - .net's non-ordinal match also matches things like "ß" and "ss".
That leads to some weird things like even if two strings compare as equal in the invariant culture, if you uppercase them in the invariant culture they may no longer be considered equal.
And that's all before you start looking at culture-variant behaviors like different cultures having different casing rules (see Turkish dotless i) or approaches to diacritic equivalence for sorting.
If I want to compare or print in my own language or the system language (I very rarely do) then I'm happy to specify that in code. And I wish the API forced me to, because I some times forget and I make code that breaks when it's run on a different machine. Which is almost never what I want.
(It should also be easy to compare strings in different ways. StringComparison.Ordinal is an overly long incantation for the frequency with which it's needed.)
Alternatively, we need two distinct string types - one for "displayed text", and one for internal stuff like an HTTP header - with no implicit conversions between the two, and with comparisons defined differently for either.
But the problem can also be flipped around and generalized to include formatting. To seem well designed I think it should be symmetric in formatting/parsing wrt what must be provided. In formatting it’s more clear that the system must assume assume format, or some operations become unergonomic (once one wants to be sloppy and allow concatenation of string and int for example). But perhaps one could compromise and just allow ints (assume invariant) but not floats (require formatter).