19

From their brief summary descriptions, it sounds like the string comparison rules StringComparison.Ordinal and StringComparison.InvariantCulture are meant to differ in how they do sorting of strings. Is that all? i.e., does that mean we can use either string comparison rule when doing an equality comparison?

string.Equals(a, b, StringComparison....)

And for extra credit: does it make a difference to the answer if we compare OrdinalIgnoreCase and InvariantCultureIgnoreCase? How?

Please provide supporting argument and/or references.

Tim Lovell-Smith
  • 15,310
  • 14
  • 76
  • 93
  • 3
    Culture matters for case invariant comparisons since some languages have strange upper/lowercase rules. For example Turkish with it's two lower and two upper case "i"s, which are matched cross-over. – CodesInChaos Jan 12 '11 at 22:15
  • Possible duplicate of [Difference between InvariantCulture and Ordinal string comparison](https://stackoverflow.com/questions/492799/difference-between-invariantculture-and-ordinal-string-comparison) – Wai Ha Lee Nov 09 '18 at 13:42

3 Answers3

26

It does matter, for example - there is a thing called character expansion

    var s1 = "Strasse";
    var s2 = "Straße";

    s1.Equals(s2, StringComparison.Ordinal);          // false
    s1.Equals(s2, StringComparison.InvariantCulture); // true

With InvariantCulture the ß character gets expanded to ss.

Ventsyslav Raikov
  • 6,882
  • 1
  • 25
  • 28
  • 2
    So it's interesting to note that `String.Equals(s1, s2, StringComparison.OrdinalIgnoreCase)` seems to be the best case insensitive alternative `(s1 == s2)`. – Matthijs Wessels Feb 20 '14 at 13:02
6

Well, it certainly matters. When you use an "ignore case" equality comparison then you're invoking a fairly massive chunk of code in the .NET framework that's aware of how casing rules work in the current culture. The rules of which are very interesting to a former-postage-stamp collector geek like me, there are some pretty odd-ball rules depending where you look. The Turkish I problem is famous, the Unicode dudes had to make an explicit exception for them.

It isn't actually code btw, it's lookup tables. Interesting in itself because it requires MSFT to maintain the /linkres command line option for the C# compiler. A compile option you cannot use in your own projects. It's solely there to get mscorlib to be able to find the .nlp files, the conversion tables for culture rules. Stored in the same subdirectory of the GAC as mscorlib.dll, the effect of the compile option.

But I digress. It stands to reason that StringComparison.OrdinalIgnoreCase is a wee bit quicker than StringComparison.InvariantCultureIgnoreCase. Just because 'invariant' means USA, home of MSFT. Hard to measure, this clocks in at nanoseconds. StringComparison.CurrentCultureIgnoreCase hits those translation tables. Dead slow when you first use it, just slower when you use them later.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
4

For the extra credit question

Community
  • 1
  • 1
Pauli Østerø
  • 6,878
  • 2
  • 31
  • 48