Q:

Chaining to clean up CompareTo

Every time I need to write a CompareTo method in C#, I hate the fact that I can't chain the tests and results like you would in JavaScript:
function int compareTo(a, b) {
    return a.Value1 - b.Value1 || a.Value2 - b.Value2 || a.Value3 - b.Value3;
}

Instead in C# this looks like:
int CompareTo(object obj)
{
    var other = obj as MyClass;
    if (other == null)
        return 0;
    int result = Value1 - other.Value1;
    if (result != 0)
        return result;
    result = Value2 - other.Value2;
    if (result != 0)
        return result;
    return Value3 - other.Value3;
}

Is there a way to write the above 'cleaner'? It doesn't have to be a one-liner like in JavaScript, but should be more readable and less error-prone.

A:

Using a generic extension method NullableCompareTo we can now make use of the ?? operator to refactor the CompareTo method to:
int CompareTo(object obj)
{
    var other = obj as MyClass;
    if (other == null)
        return 0;
    return Value1.NullableCompareTo(other.Value1)
        ?? Value2.NullableCompareTo(other.Value2)
        ?? Value3.CompareTo(other.Value3);
}

Extension method
public static class ComparableExtensions
{
    /// <summary>
    /// Same as CompareTo but returns null instead of 0 if both items are equal.
    /// </summary>
    /// <typeparam name="T">IComparable type.</typeparam>
    /// <param name="this">This instance.</param>
    /// <param name="other">The other instance.</param>
    /// <returns>Lexical relation between this and the other instance or null if both are equal.</returns>
    public static int? NullableCompareTo<T>(this T @this, T other) where T : IComparable
    {
        var result = @this.CompareTo(other);
        return result != 0 ? result : (int?)null;
    }
}

