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.ProductCategories.ParentCategoryID >= 1 && summerCatalog.Products.ProductCategories.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:
/// Returns whether the value is between the 2 specified boundaries.
/// <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<T> 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.ProductCategories.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.ProductCategories;
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?