Injecting Ruby Readability into C#

If you’ve read any of my previous posts (you should, there are only two of them), then you know that I’m a big fan of keeping things simple.  As a matter of fact, it’s right there in my tagline.  You don’t even have to read a post to know that.  In my opinion, simplicity is key in all areas of software development, from Agile practices to the coding itself.

There are infinite ways to simplify coding.  Some necessary, some not so necessary, but minor improvements over time can make a massive difference in the way that you write (and think about) code.

There are some improvements that can be made to the basic plumbing of the C# language, such as the for-loop.  Now, the for-loop has been a tried and true flow control construct for decades and serves it’s purpose exceedingly well.  However, and I hope that I’m not the only developer that still does this, using a for-loop causes me to pause for a moment and work out the logic of the loop by doing a few “mental iterations”.  This is a minor inconvenience.  I know what I want to do… and I know that I want to do it x times.  So how can we improve upon it?  Let’s take a lesson from the increasingly popular scriping language, Ruby.

The Ruby language is extremely “readable”.  I like this.  It helps me to more quickly connect my infinitely fragmented thoughts to real, tangible code.  The Ruby language introduces the Times method, which practically subsumes the for-loop construct.  If I want to perform a certain action 5 times, I can simply enter:

5.times (puts "Everything's zen.")

Everything’s zen, indeed. Fortunately, it’s pretty easy to slice off a piece of this readability and stick it into my language of choice (and comfort), C#.  With the introduction of C# 3.0, we now have the ability to create extension methods and lambda expressions, two language features that come into play in this situation.  Let’s jump into some code…

public static void Times( this int howMany_, Action<int> toDo_ )
{
    if ( toDo_ == null )
        throw new ArgumentNullException( "toDo_" );

    for ( int iterationCt = 0; iterationCt < howMany_; iterationCt++ )
        toDo_( iterationCt + 1 );
}

There are a few things to note here.  First, we want to check to make sure than an actual delegate has been passed in.  If not, it’s time to bail.  Also, I can already hear you crying foul that I’m using a one-based index within my loop.  I just feel that given the context of the extension method, this makes it more readable.  If you’re still crying foul, just write your own.  Come on, it’s seven lines of code.  Finally, I’m extending the Int32 type.  Feel free to extend this method to other integer types as well.

Let’s give it a shot.

5.Times( i => Console.WriteLine( "Everything's zen." ) );

Alright, it works like a champ.  I’m sure that you can find other minor areas of your language of preference that can be improved in similar ways.  Let me know what you come up with.


About this entry