I have yet to decide whether Extension Methods in C# are a boon or bane. I’ve already several times, been frustrated by Intellisense not showing me a method that was legal somewhere else, until I could figure out what using statement brought that extension method into scope. On one hand Extension Methods can be used to simplify code, on the other, I see them as the source of much confusion as they become popular.
Worse yet, they have potential for more about than the blink tag, imho.
The one place I see extension methods being instrumental is in defining fluent interfaces, yet another practice I have yet to decide whether I am in favor of or not. Partially, because I don’t see them as intrinsically easier to read. Partially because they allow for much syntactic abuse.
So today, I created a fluent interface for an operation that I wish was just support in the language in the first place — the between operator. It exists in some SQL dialects and is a natural part of so many math equations. I wish I could just write:
if( 0.5 < x < 1.0 ) { // do something }
Instead, I’ll settle for this:
if( x.Between(0.5).And(1.0) ) { // do something }
The first part is easy, it’s just an Extension Method on double. And if I just had it take the lower and upper bound, then we would have been done. But this is where the fluent interface bug bites me and I want to say And. This means, that Between can’t return a boolean. It needs to return the result of the lower bound test and the value to be tested. That means that Between returns a helper class, which has one method And, which finally returns the boolean value.
public static class DoubleExtensions { public static BetweenHelper Between(this double v, double lower) { return new BetweenHelper(v > lower, v); } public struct BetweenHelper { public bool passedLower; public double v; internal BetweenHelper(bool passedLower, double v) { this.passedLower = passedLower; this.v = v; } public bool And(double upper) { if (passedLower && v < upper) { return true; } else { return false; } } } }
That’s a lot of code for a simple operation and it’s still questionable whether it really improves readability. But it is a common enough operation if you have a lot of bounds checking, that it might be worth throwing into a common code dll. I’ve yet to make up my mind, I mostly did it because i wanted to play with the syntax.
This is very nice idea.