Categories: .Net, P# Posted by mheydt on 8/15/2007 3:47 PM | Comments (0)
Revisting the iterator pattern, revisited again
I was playing around with .NET 3.5 extension methods and lambda functions and it hit me that this will very closely get me to the syntax that I desire for iterating across collections.  If you remember from my earlier post, I was looking for a syntax like the following (which is kind of both C# and ruby-ish in style):

    int[] ia = new int[] { 5, 4, 3, 2, 1};
    iterate ia |x| do { Console.WriteLine(x); } where { x < 3; };



Well, what I was able to come up with is an extension method that can add an iterate method to a collection (basically, anything IEnumerable) that can take two lambda methods, one for selecting items, and the other for processing on each selected item.  For example, the following actual C# code is possible:

    int[] ia = new int[] { 5, 4, 3, 2, 1};
    ia.iterate(x => x < 3, x => Console.WriteLine(x));


The output of running this c# is:

2

1

One of the neat things about the lamba methods is that they can operate on variables declared in local method scope.  For example, take this example of building a list on the items between 2 and 4 and then printing out that list:

    int[] ia = new int[] { 5, 4, 3, 2, 1};
    List<int> result = new List<int>();
    ia.iterate(x => x >= 2 && x <= 4, x => result.Add(x));
    result.iterate(x => Console.WriteLine(x));


This prints out:

4

3

2

The code for this extension method is the following:

    public static class IterateExtension
    {
        public delegate void operationdelegate(object o);
        public delegate void operationdelegate<T>(T o);
        public delegate void selectiondelegate(object o);
        public delegate bool selectiondelegate<T>(T o);
        public static void iterate<T>(this IEnumerable<T> objects, operationdelegate<T> od)
        {
            foreach (T o in objects)
            {
                od(o);
            }
        }

        public static void iterate<T>(this IEnumerable<T> objects, selectiondelegate<T> sd, operationdelegate<T> od)
        {
            foreach (T o in objects)
            {
                if (sd(o))
                    od(o);
            }
        }

        public static void iterate(this IEnumerable objects, operationdelegate od)
        {
            foreach (object o in objects)
            {
                od(o);
            }
        }

        public static void iterate<T>(this IEnumerable objects, selectiondelegate<T> sd, operationdelegate<T> od)
        {
            foreach (T o in objects)
            {
                if ((sd(o)))
                    od(o);
            }
        }
    }

Comments