Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is generally best to use -- StringComparison.OrdinalIgnoreCase or StringComparison.InvariantCultureIgnoreCase?

People also ask

What is difference between InvariantCultureIgnoreCase and OrdinalIgnoreCase?

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.

What is the use of StringComparison OrdinalIgnoreCase?

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.

What is StringComparison CurrentCultureIgnoreCase?

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 of String overloads in Microsoft .NET 2.0. Specifically, data that is designed to be culture-agnostic and linguistically irrelevant should begin specifying overloads using either the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase members of the new StringComparison enumeration. These enforce a byte-by-byte comparison similar to strcmp that not only avoids bugs from linguistic interpretation of essentially symbolic strings, but provides better performance.


It all depends

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:

  1. Set the culture explicitly and perform a case insensitive compare using unicode equivalence rules.
  2. Set the culture to the Invariant Culture and perform case insensitive compare using unicode equivalence rules.
  3. Use OrdinalIgnoreCase which will uppercase the string using the InvariantCulture and then perform a byte by byte comparison.

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.

  • If I was writing a line-of-business app which was only used by Turkish users, I would be sure to use method 1.
  • If I just needed a simple "fake" case insensitive compare, for say a column name in a db, which is usually English I would probably use method 3.

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.