InvariantCultureIgnoreCase uses comparison rules based on english, but without any regional variations. This is good for a neutral comparison that still takes into account some linguistic aspects. OrdinalIgnoreCase compares the character codes without cultural aspects.
OrdinalIgnoreCase. The StringComparison has the OrdinalIgnoreCase property and treats the characters in the strings to compare as if they were converted to uppercase (using the conventions of the invariant culture) and then it performs a simple byte comparison and it is independent of language.
The StringComparer returned by the CurrentCultureIgnoreCase property can be used when strings are linguistically relevant but their case is not. For example, if strings are displayed to the user but case is unimportant, culture-sensitive, case-insensitive string comparison should be used to order the string data. .
Newer .Net Docs now has a table to help you decide which is best to use in your situation.
From MSDN's "New Recommendations for Using Strings in Microsoft .NET 2.0"
Summary: Code owners previously using the
InvariantCulture
for string comparison, casing, and sorting should strongly consider using a new set ofString
overloads in Microsoft .NET 2.0. Specifically, data that is designed to be culture-agnostic and linguistically irrelevant should begin specifying overloads using either theStringComparison.Ordinal
orStringComparison.OrdinalIgnoreCase
members of the newStringComparison
enumeration. These enforce a byte-by-byte comparison similar tostrcmp
that not only avoids bugs from linguistic interpretation of essentially symbolic strings, but provides better performance.
Comparing unicode strings is hard:
The implementation of Unicode string searches and comparisons in text processing software must take into account the presence of equivalent code points. In the absence of this feature, users searching for a particular code point sequence would be unable to find other visually indistinguishable glyphs that have a different, but canonically equivalent, code point representation.
see: http://en.wikipedia.org/wiki/Unicode_equivalence
If you are trying to compare 2 unicode strings in a case insensitive way and want it to work EVERYWHERE, you have an impossible problem.
The classic example is the Turkish i, which when uppercased becomes İ (notice the dot)
By default, the .Net framework usually uses the CurrentCulture for string related functions, with a very important exception of .Equals
that uses an ordinal (byte by byte) compare.
This leads, by design, to the various string functions behaving differently depending on the computer's culture.
Nonetheless, sometimes we want a "general purpose", case insensitive, comparison.
For example, you may want your string comparison to behave the same way, no matter what computer your application is installed on.
To achieve this we have 3 options:
Unicode equivalence rules are complicated, which means using method 1) or 2) is more expensive than OrdinalIgnoreCase
. The fact that OrdinalIgnoreCase
does not perform any special unicode normalization, means that some strings that render in the same way on a computer screen, will not be considered identical. For example: "\u0061\u030a"
and "\u00e5"
both render å. However in a ordinal compare will be considered different.
Which you choose heavily depends on the application you are building.
Microsoft has their set of recommendations with explicit guidelines. However, it is really important to understand the notion of unicode equivalence prior to approaching these problems.
Also, please keep in mind that OrdinalIgnoreCase is a very special kind of beast, that is picking and choosing a bit of an ordinal compare with some mixed in lexicographic aspects. This can be confusing.
I guess it depends on your situation. Since ordinal comparisons are actually looking at the characters' numeric Unicode values, they won't be the best choice when you're sorting alphabetically. For string comparisons, though, ordinal would be a tad faster.
It depends on what you want, though I'd shy away from invariantculture unless you're very sure you'll never want to localize the code for other languages. Use CurrentCulture instead.
Also, OrdinalIgnoreCase should respect numbers, which may or may not be what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With