About the author

Steven HarmanSteven Harman is a passionate developer who believes that writing great software isn't just a job, its a craft.

ASP.NET MVP

For recent posts and more about me, scroll to the bottom.

Subscribe

  • Subscribe to my feed. via RSS
  • Subscribe via email via email

Jobs

Badges

  • Subtext Project
  • Support Subtext
  • HiddenNetwork.com Banner

Get Ruby-esq Each Iterators in C# 3.0

Yes, Ruby and other dynamic languages are all the rage these days.

Yes, using Extension Methods in C# 3.0 is overplayed.

But you know what... I don’t care! So I’m going to show you an Extension Method that will bring a little Ruby-goodness to your hum-drum C# world.

The Ruby goodness

One of my favorite control structures in Ruby is the each method. This method can be used on any string, array, or hash to quickly iterate over each character of a string, item of an array, or key/value pair of a hash.

That’s not so special. What is special is that we can execute a block of code on each of those characters, items, or key/value pair, respectively.

   1:  heros = ['phil', 'rob', 'scott', 'the gu']
   2:   
   3:  heros.each do |hero|
   4:      puts "I have a hero named " + hero.capitalize
   5:  end
   6:   
   7:  # I have a hero named PHIL
   8:  # I have a hero named ROB
   9:  # I have a hero named SCOTT
  10:  # I have a hero named THE GU

Granted, that code is really simple, but the power is in the code block between the do and end keywords. That code block is similar to an anonymous method in C# parlance. Meaning, we can put as much, or little, code in there as needed. And each item being iterated over is passed into the block as a parameter between the pipes.

To review, the above is simply an array of strings. We’re iterating over the array, passing each string into code block via the hero parameter. And then the code block acts on the parameter do something with it. Pretty simple, yeah?

Get it in C#

C# 3.0 introduced a whole world of new and powerful methods for dealing with collections of... well of things. We can filter, search, order, and lots more. However, there’s not really a built-in way to iterate over the most basic of collection data types - the IEnumerable<T> interface.

Well, we do now!

   1:  public static void Each<T>(this IEnumerable<T> items, Action<T> action)
   2:  {
   3:      foreach (var item in items)
   4:      {
   5:          action(item);
   6:      }
   7:  }

Sure, the implementation is crazy simple, but it allows us to write far more expressive code and reduce some of the visual clutter that often gets in the way. Its all about solubility baby!

We can take lines 1-4 below, and collapse them into line 6.

   1:  foreach (String hero in heros)
   2:  {
   3:      System.Print("I have a hero named " + hero.ToUpper());
   4:  }
   5:   
   6:  heros.Each(hero => System.Print("I have a hero named " + hero.ToUpper()));

Or if we needed more than a single line of code, we could do something like

   1:  byte[] timestamp = new byte[len];
   2:  timestamp.Each(b => 
   3:    {
   4:      len--;
   5:      timestamp[len] = (byte) RandomInt();
   6:    });

Again, not exactly the most useful code in the world, but you can see where I’m going. If that code looks kinda' familiar, its because it is. :) I lifted it almost directly from my Value Type Parameters Are Still Value Types, Even in a Lambda Expression post.

So there you have it, some Ruby-esq deliciousness to help brighten a dreary statically-typed day in the world of C#. Boy, I loves me some Lambda expressions!

What others are saying.

# re: Get Ruby-esq Each Iterators in C# 3.0
Gravatar Haacked
Jan 15, 2008
Interestingly enough, the Array class has a static ForEach method that does what you've done here, but there's no equivalent method on IEnumerable.

Nicely done.
# Get Ruby-esq Each Iterators in C# 3.0
Gravatar DotNetKicks.com
Jan 15, 2008
You've been kicked (a good thing) - Trackback from DotNetKicks.com
# re: Get Ruby-esq Each Iterators in C# 3.0
Gravatar Matt Blodgett
Jan 17, 2008
Great post.

It wasn't until I started reading "Programming Ruby" a few weeks back that I really understood the usefulness and potential of C# 3.0's new features.
# Expectation Based Testing with Mocks
Gravatar StevenHarman.net
Jan 27, 2008
Expectation Based Testing with Mocks
# re: Get Ruby-esq Each Iterators in C# 3.0
Gravatar Jimmy Bogard
Feb 07, 2008
I like your way better than my way:

grabbagoft.blogspot.com/.../...ethods-in-c-30.html

Didn't really need the extra "Do" method....
Comments have been closed on this topic.