All types that implement the IComparable or IComparable interface can be compared, using the CompareTo method implemented by each type. All primitive types implement IComparable<T>, including char and string. LINQ's Min(IEnumerable) and Max(IEnumerable) use this implementation to find the minimum or maximum in an enumerable.
String Comparisons
Comparing strings though is a bit more interesting than comparing integers. The strings are typically compared in dictionary order (lexicographically) but ... whose dictionary? Different languages have different sorting rules, and sometimes two letters are considered a single one. Even Danes forget that AA is equivalent to Å in Danish.
The dictionary used to compare strings is provided by the CultureInfo class. By default, the current thread's culture is used which typically matches the culture of the end user (in desktop applications) or the system locale in server applications. In a Danish culture for example, AA is treated differently from aa - I think one of them is ordered after other letters of the same case and the other isn't, but don't ask me which.
The InvariantCulture specifies a locale-insensitive culture that can be used to handle strings the same way in every locale. It uses mostly sensible settings (eg . for the decimal point) except dates, where it uses the US format instead of the ISO8601 (YYYY-MM-DD) format as everyone would expect.
Custom comparisons
It's possible to specify a different comparison method by passing a class that implements IComparer to any LINQ methods affected by order. Min(IEnumerable,IComparer) is one example.
The StringComparer class contains some predefined comparers :
- CurrentCulture is the default
- CurrentCultureIgnoreCase uses the current culture but ignores case, so
A is equal to a. This is very useful eg in dictionaries.
- InvariantCulture and
InvariantCultureIgnoreCase use the Invariant culture for ordering
- Finally, Ordinal and
OrdinalIgnoreCase don't use a dictionary but compare the Unicode values of the characters. That's the fastest option if you don't care about locale rules