I recently discovered that C# 2.0 was more then generic, you also get anonymous methods, partial and static classes, and some others...
The more I work with generic and anonymous methods, the more I feel like hacking with a dynamic language such as Ruby, Python or Boo (Boo is not dynamic I know, but so close).
My following example is somewhat trivial in this case, iterating a simple list is better done with a foreach block. But this pattern could be useful to browse some more complex hierarchy like a tree or a graph.
So here's the implementation of the actual visitor:
And now to call it we specify an anonymous method with a block executed on each iteration. The delegate type is inferred by the compiler.
This is starting to look a lot like closures, don't you think ?
A rather more useful application would be to add a ForEach(delegate) to Castle's ActiveRecord so we could do something like this:
Or even cooler (ActiveRecord.Update() would be called after each iteration.):
The more I work with generic and anonymous methods, the more I feel like hacking with a dynamic language such as Ruby, Python or Boo (Boo is not dynamic I know, but so close).
My following example is somewhat trivial in this case, iterating a simple list is better done with a foreach block. But this pattern could be useful to browse some more complex hierarchy like a tree or a graph.
So here's the implementation of the actual visitor:
public class ListVisitor<T>
{
public delegate void VisitDelegate(T visited);
private IList _list;
public ListVisitor(IList list)
{
_list = list;
}
public void Visit(VisitDelegate callback)
{
foreach (T item in _list)
{
callback.Invoke(item);
}
}
}
And now to call it we specify an anonymous method with a block executed on each iteration. The delegate type is inferred by the compiler.
ArrayList list = new ArrayList("This is a test".Split(''));
ListVisitor<string> visitor = new ListVisitor<string>(list);
visitor.Visit(delegate(string obj) { Console.WriteLine(obj); });
This is starting to look a lot like closures, don't you think ?
A rather more useful application would be to add a ForEach(delegate) to Castle's ActiveRecord so we could do something like this:
int greatTotal = 0;
Order.ForEach(delegate(Order o) { greatTotal += o.Total; });
Or even cooler (ActiveRecord.Update() would be called after each iteration.):
Order.UpdateEach(delegate(Order o) { if (o.Date > DateTime.Now.Date) o.Closed = true; });