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

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.