Search code examples
c#stringcompareto

2 questions about CompareTo() method in C#


I have 2 questions about the CompareTo() method in c#:

  1. I read this method compares between the letters in two strings and returns the difference between the Unicode values of the first pair of letters, that aren't the same in the both strings. But when I run it, it always returns -1, 0, or 1. For example:
string s1, s2;

s1 = "AARZNML";
s2 = "AARZK";

Console.WriteLine(s1.CompareTo(s2));

In the book it was said that the code must return -24, but it returns -1, when I run it.

  1. What is CompareTo() method supposed to return when I compare a string with uppercase letters and a string with lowercase lowercase. For example I ran this code:
string s1, s2;

s1 = "A";
s2 = "a";

Console.WriteLine(s1.CompareTo(s2));

and it returned 1, how can it be? Because 'A' is before 'a' in ASCII Table.


Solution

  • But when I run it, it always returns -1, 0, or 1.

    Because the only contract string.CompareTo(string? strB) has is that it:

    Returns

    A 32-bit signed integer that indicates whether this instance precedes, follows, or appears in the same position in the sort order as the strB parameter.

    Value Condition
    Less than zero This instance precedes strB.
    Zero This instance has the same position in the sort order as strB.
    Greater than zero This instance follows strB. -or- strB is null.

    So implementation is free to return any integer matching the rules. It is quite common to implement IComparable.CompareTo in a way that it uses only those 3 numbers (-1, 0, 1) as return values but this is not guaranteed in general.

    Note that:

    Both overloads of the CompareTo method perform culture-sensitive and case-sensitive comparison. For code clarity, we recommend that you avoid the CompareTo method and call the Compare method instead.

    I.e. the following:

    foreach(var s in new []{s1, s2}.Order(StringComparer.CurrentCulture))
        Console.WriteLine(s);
    

    Prints a and then A, so in default ordering (on my machine with my default culture) A follows a, so the result is of ComapareTo is Greater than zero.

    Demo @sharplab.io

    As experiment you can set globalization-invariant mode (add <InvariantGlobalization>true</InvariantGlobalization> entry to PropertyGroup in .csproj) which changes the behaviour - for me result was -32 and A is printed before a.