+N Consulting, Inc.

Between - Extension method to shorten notation

Sometimes I just write code. And sometimes I clean up my code. Most of the times, I focus on the meat of the methods, hacking away at verbose or lengthy flows, re-factoring out common code, trying to untangle overly complex logic etc.

Recently, I noticed that many of the conditional terms I write span very long lines and are a bit cumbersome to read. The reason for that is that many of the variable names are long, or the properties or both and that often the comparison is on a property of an object or member of a collection etc.

So for instance:

if (summerCatalog.Products[0].ProductCategories[0].ParentCategoryID >= 1 && summerCatalog.Products[0].ProductCategories[0].ParentCategoryID <= 4)
{
//...
}
  • Can become quite long.
  • Long is not easy to read.
  • Long is not easy to maintain.
  • Long is not easy to think through.

What I really wanted to say is if [value] is between [a] and [b].

Of course, one could say “lets just make the variable names shorter”. But that flies in the face of self explanatory plain naming. So abbreviating for the sake of short-lineliness (New word! You heard it her first!) is out.

Well, this is just screaming “EXTENSION METHODS” doesn’t it?

Here we go then:

/// <summary>
/// Returns whether the value is between the 2 specified boundaries.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value to compare</param>
/// <param name="minValueInclusive">The min value (inclusive).</param>
/// <param name="maxValueInclusive">The max value (inclusive).</param>
/// <returns>True if the value is equal to or between the boundaries; False otherwise.</returns>
public static bool Between<T>(this T value, T minValueInclusive, T maxValueInclusive) where T : IComparable<T>
{
if (minValueInclusive.CompareTo(maxValueInclusive) > 0)
{
throw new ArgumentException("minimum value must not be greater than maximum value");
}
return (value.CompareTo(minValueInclusive) >= 0 && value.CompareTo(maxValueInclusive) <= 0);
}

The Between function takes any object which supports IComparable and performs syntactic sugar comparison with the inclusive min and max values. What’s more, it adds a basic sanity check for the comparison. How many times do I do that sanity check in my normal code (!)?

Now the conditional is

if (summerCatalog.Products[0].ProductCategories[0].ParentCategoryID.Between(1, 4)) 
{
///...
}

At least I don’t have to refactor this in my brain while reading.

Sure, you might say, but you could have just de-referenced the deep value and then have a shorter conditional, like so:

Category category = summerCatalog.Products[0].ProductCategories[0];
if (category.ParentCategoryID >= 1 && category.ParentCategoryID <= 4)
{
//...
}

Yes - of course - but it adds a line of code, places the burden of reading the very common idiom ( x >= a && x <= b) on me, and I constantly stumble on the lest-than-or-equal vs. less-than and it doesn’t check for my boundaries being inadvertently swapped.

So there you have it. A simple extension cuts down your lines of code, makes long text shorter and saves lives. Which begs the question: is this already part of the language - and should it be?

Notice

We use cookies to personalise content, to allow you to contact us, to provide social media features and to analyse our site usage. Information about your use of our site may be combined by our analytics partners with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website.