March 27, 2009

A C# implementation of the Ruby 'each' iterator

If you ever had a look at Ruby you probably saw things like the following in one of the many tutorials:

s1 = 0
(10...20).each { |x| s1 += x*x }
puts s1

s2 = 0
[3, 7, 9].each { |x| s2 += x*x }
puts s2

Really cool. First thing I loved straight away is the easy notation for ranges.
And then, of course, there's the each iterator which takes a block as parameter. Simply fantastic.

As a software developer who uses C# for most of his tasks at the moment, I was jealous. But then I thought: why just not do the same thing in C#?

Well, of course there is no fancy tripe-dot range notation is C#. But we can do it like this:

class Range
public static IEnumerable<int> FromTo(int from, int to)
int pos = from;
while (pos <= to)
yield return pos;

Pretty easy to do with the help of the yield keyword.
OK, and what about each? You can implement that using a extension method:

static class IteratorExtensions

public static void Each<T>(this IEnumerable<T> enumerable, Action<T> action)
foreach (var item in enumerable)

This defines a new method Each for IEnumerable<> types. It takes a parameter of type Action, which is a void method with one parameter of type T. Action is defined in the System namespace.
Now let's take Range.FromTo and Each together and we rewrite the above Ruby script in C#:

int s1 = 0;
delegate(int x)
s1 += x*x;

Hmm, that is nowhere near the simple notation of the Ruby script...
But wait. Instead of using an anonymous method we also can used a lambda construct. Let's try it on the second part of the Ruby script:

int s2 = 0;
new[] { 3, 7, 9 }.Each(x => s2 += x*x);

Much better! Actually it almost looks like the Ruby script.
Conclusion: Ruby is nice, but C# isn't too bad either... ;-)
blog comments powered by Disqus