The C# "extension method" feature lets you implement static methods which "magically" act like they're instance methods. It's a neat feature which the .NET Framework uses extensively. It's also a great way to implement some convenience functions.
Brandt found some "convenience" functions which were exploiting this feature.
public static bool IsLessThen<T>(this T a, T b) where T : IComparable<T>
=> a.CompareTo(b) < 0;
public static bool IsGreaterThen<T>(this T a, T b) where T : IComparable<T>
=> a.CompareTo(b) > 0;
public static bool And(this bool a, bool b)
=> a && b;
public static bool Or(this bool a, bool b)
=> a || b;
public static bool IsBetweensOrEqual<T>(this T a, T b, T c) where T : IComparable<T>
=> a.IsGreaterThen(b).Or(a.Equals(b)).And(
a.IsLessThen(c).Or(a.Equals(c))
);
Here, we observe someone who maybe heard the term "functional programming" and decided to wedge it into their programming style however it would fit. We replace common operators and expressions with extension method versions. Instead of the cryptic a || b
, we can now write a.Or(b)
, which is… better?
I almost don't hate the IsLessThan
/IsGreaterThan
methods, as that is (arguably) more readable. But wait, I have to correct myself: IsLessThen
and IsGreaterThen
. So they almost got something that was (arguably) more readable, but with a minor typo just made it all more confusing.
All this, though, to solve their actual problem: the TimeSpan
data type doesn't have a "between" comparator, and at one point in their code- one point- they need to perform that check. It's also worth noting that C# supports operator overloading, and TimeSpan
does have an overload for all your basic comparison operators, so they could have just done that.
Brandt adds:
While you can argue that there is no out of the box 'Between' functionality, the colleague who programmed this ignored an already existing extension method that was in the same file, that offered exactly this functionality in a better way.