Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

Yet another use for Extension methods : Extending IComparable<T>

I keep finding more uses for extension methods. This time it's extending IComparable<T>. The API signature for IComparable<T> has been around since the dawn of C: if the left is less than the right, return something less than 0, if left is greater than right, return something greater than 0, and if they are equivalent, return 0. Well, its readability leaves a bit to be desired.

So I wrote this set of extension methods for any type T that implements IComparable<T>:

public static class EquatableExtensions
{
    public static bool GreaterThan<T>(this T left, T right) where T : IComparable<T>
    {
        return left.CompareTo(right) > 0;
    }

    public static bool LessThan<T>(this T left, T right) where T : IComparable<T>
    {
        return left.CompareTo(right) < 0;
    }

    public static bool GreaterThanOrEqual<T>(this T left, T right) where T : IComparable<T>
    {
        return left.CompareTo(right) >= 0;
    }

    public static bool LessThanOrEqual<T>(this T left, T right) where T : IComparable<T>
    {
        return left.CompareTo(right) <= 0;
    }

    public static bool Equal<T>(this T left, T right) where T : IComparable<T>
    {
        return left.CompareTo(right) == 0;
    }
}

These methods mean I can write this:

if (foo.GreaterThan(bar))

instead of

if (foo.CompareTo(bar) > 0)

personally, I find the former much easier to read.

Ok, this is not rocket science, but it's useful, and it improves the readability of quite a bit of the code I work with on a day to day basis.

Published Mon, Jan 7 2008 9:19 AM by wwagner

Comments

# re: Yet another use for Extension methods : Extending IComparable<T>@ Tuesday, January 08, 2008 4:08 AM

Don't you have to provide the generic type when you use it as an extension method?

In your example you use:

if (foo.GreaterThan(bar))

instead of

if (foo.GreaterThan<SomeType>(bar))

by Koen

# re: Yet another use for Extension methods : Extending IComparable<T>@ Tuesday, January 08, 2008 11:20 AM

And for those not familiar with all the nuances of generics and IComparable<T>, this doesn't mean you can do this:

Int16 left = 10;

Int32 right = 2;

Trace.WriteLine(left.GreaterThan(right));

...which is a good thing; but is slightly different than not using these extension methods:

Int16 left = 10;

Int32 right = 2;

Trace.WriteLine(left.CompareTo(right) > 0);

...which compiles without error--only to result in a runtime error when executed.  This results in a call to IComparable.CompareTo(object); but many IComparable implementations don't support comparison to many other types (plus it would incur some boxing).  

BTW, "dawn of C(colon)"?

# a salmon of doubt &raquo; CodeMash Day 2 Not-So-Mega-Summary@ Friday, January 11, 2008 9:50 PM

Pingback from  a salmon of doubt &raquo; CodeMash Day 2 Not-So-Mega-Summary

# re: Yet another use for Extension methods : Extending IComparable<T>@ Thursday, January 17, 2008 6:52 AM

Koen,

When a generic method's parameters can be inferrd, you don't need the angle brackets.

if (foo.GreaterThan(bar)) compiles just fine.

The compiler knows that foo is <SomeType> and generates the write method call.

by wwagner