Fun with Delegates, or How to make .Net more like Ruby 2
I’ll admit it, I’m a Ruby fan. There are certain aspects of programming with that language that are really fun. While I don’t have the privilege of working with it every day, I’m working with it enough. With yesterday’s look at the world of LINQ, I decided to play a bit more with delegates and extension methods. For the other Ruby fans out there, it is true that C# is both a statically typed language and those types are locked in at compile time. However, there are ways to make C# behave more like Ruby. Sure you can use the var keyword which just means that the type isn’t decided until the first assignment. But I’m going to look at imitating the way Ruby does looping in C#.
list = ["one", "two", "three"]
list.each {|item| puts item}
# Alternately:
list.each do |item|
puts item
end
Perusing the .Net APIs, your IEnumerable<T> or List<T> objects don’t have an Each() method. Although it’s not difficult to add it after the fact. The process is not hard. The first step is to create an extension method. Extension methods are much like Ruby mixins, and are implemented very similarly. As long as our mixin class in in scope, so is our extension method. Let’s look at how it would look in C#:
string[] list = {"one", "two", "three"};
list.Each( item => Console.WriteLine(item) );
// Alternately:
list.Each(
delegate(string item)
{
Console.WriteLine(item);
});
The code to implement this really is not difficult to do, but it requires some understanding of the underlying mechanisms that make it possible:
public static class IEnumerableExtensions
{
public static void Each<T>(this IEnumerable<T> list,
Action<T> callback)
{
foreach(T item in list)
{
callback(item);
}
}
}
To better understand what’s going on here, I’m going to have to call out a few things. First, the mixin class IEnumerableExtensions must be static. Without the static keyword in front of the class the CLR will not be able to look inside for extension methods. That keyword also tells the compiler that all members of this class will also be static. The class cannot be instantiated in any way. Functionally, it behaves a lot like a Ruby module, which is why I’m calling it a mixin class. Note: the name of the class really doesn’t matter, but convention adds the word “Extensions” to the class or interface we are adding functionality to.
Next, the first argument of an extension method includes the keyword “this” and the type we are extending as the first parameter. Without the keyword “this” we would have just another random static method. Also note, this is a feature that is not possible in Java without bytecode manipulation or dynamic proxy chicanery. Perhaps that will change in the future. For those that used to know how C++ objects worked, the structure here makes a lot of sense. It’s similar to the idiom popular among C programmers to pass the struct being modified as the first parameter. I chose the IEnumberable interface because the same method will work on anything that implements that interface: which is exactly how Ruby attacks the problem. Essentially Ruby has an Enumerable module (mixin) that defines all the extra methods the collection classes can use.
We used generics here to provide the same idioms and levels of type checking that come with the .Net platform. Even when you are mixing in concepts derived from other languages, you should never completely throw away the principles in the language you are using. The generics allow us to use the method preserving all the type safety built into the language without requiring us to write a number of overloads. This helps using the method feel a little more Ruby-like without ignoring C# principles.
Lastly, I want to point out the type Action. It is a delegate defined by the .Net framework, along with its companion “Func”. The only difference between the two is that Action does not return anything and Func does. Instead of creating my own delegates, I simply used what was already available. With the pair of delegates supplied, we can have a lot of fun. For example, let’s say we wanted to derive a list of answers from executing the same function across all the members of a set of values. One example would be to derive the Root Mean Square (RMS) value on a set of numbers. Our extension method would look like this:
public static List<TResult> Collect<T,TResult>(
this IEnumerable<T> list, Func<T,TResult> callback)
{
List<TResult> answers = new List<TResult>();
foreach (T item in list)
{
answers.Add(callback(item));
}
return answers;
}
The way you would use the “Derive” method we just defined to calculate the RMS would look something like this:
double[] values = {1.0, 4.0, 3.0};
double rms = Math.Sqrt(
values.Collect(x => x * x).Sum() / values.Count());
Console.WriteLine("RMS is: {0}", rms);
The “Derive” method as it is written will also allow you to do a mass conversion of all the elements in one IEnumerable object into a new list. For example, if you had an array of numbers and you wanted a set of strings it can be done with just one line:
double[] values = {1.0, 4.0, 3.0};
List<string> conversion = values.Derive( item => item.ToString() );
conversion.Each( item => Console.WriteLine(item) );
Your creativity is bounded only by your imagination.

I’m confused. You seem to know about LINQ to objects. So why are you doing this the hard way?
Your Collect (Derive?) method is just LINQ’s Select() method, implemented eagerly instead of lazily. You missed the fact that List has a ForEach() method. And you used LINQ’s Sum() but didn’t spot LINQ’s Average() method (which will give you the average of a sequence without iterating it twice).
Showing that LINQ to objects is just a set of simple utility methods is great - it’s good to explain how there’s nothing special about the core .NET libraries, they’re just code you could write yourself in many cases. Just not sure whether you’ve quite shared that realisation here…
Keep in mind, I’m new to .NET, but I’m familiar with Ruby and Java. What I did was use Ruby methods there. I’m in the process of familiarizing myself with the platform, but I do have tunnel vision at the moment.
I appreciate all the information you and others can share. I did realize after I wrote the article a couple of the points you mentioned (ForEach() on List and the LINQ select method). I didn’t know about the Average() method though. Thanks for pointing that out.
There’s a lot of cool features in .NET, and that’s part of the problem. There’s a lot.