Well, I missed MVP Summit this year, so while fellow MVPs enjoying together in Redmond I'm playing with C# 3.0 at home. And I'm in the process of Ruby learning, so what I spotted immediately is the lack (correct me if I'm wrong) of Each() and Map() support in .NET 3.5 collections.
In Ruby you can apply a block of code to each element in a collection using very elegant each() method:
[1,2,3].each { |item|
puts item*item }
Each() method is basically a Visitor pattern implementation. I wonder why no such handy method exists in .NET 3.5? Dozens and dozens of new extension methods on collections covering every single aspect of collection manipulation from filtering to aggregation, but no basic functional programming facilities like Each() and Map()? Probably whoever at Microsoft decided foreach loop is still preferable solution for processing each element in a collection. That's what foreach does and does well.
...What would be advantages of having Each() method instead of foreach loop?
So I put together some quick implementation of IEnumerable.Each(subroutine) and IEnumerable.EachIndex(subroutine) extension methods after Ruby's
IEnumerable.Each(subroutine) extension method calls given subroutine (just a function returning void) once for each element in the collection, passing that element as a parameter.
IEnumerable.EachIndex(subroutine) extension method does the same, but but passes the index of the element instead of the element itself.
With those two methods I can process collections in Ruby-style functional code style:
int[] squares = new int[10]; squares.EachIndex(i => squares[i] = i * i); squares.Each(val => Console.WriteLine(val));
The implementation is suspiciously easy:
using System; using System.Collections.Generic; using System.Linq; namespace Test { public static class MyIEnumerableExtensions { public static void Each<TSource>(this IEnumerable<TSource> source, Action<TSource> action) { if (source == null) { throw new ArgumentNullException("source"); } if (action == null) { return; } foreach (TSource item in source) { action(item); } } public static void EachIndex<TSource>(this IEnumerable<TSource> source, Action<int> action) { if (source == null) { throw new ArgumentNullException("source"); } if (action == null) { return; } int i = 0; IEnumerator<TSource> enumerator = source.GetEnumerator(); while (enumerator.MoveNext()) { action(i++); } } } }Cool. Now what about transforming collection elements, I mean Map()?