Iterators: a flag for simplification ?

Posted Tue, Apr 21 2009 13:02 by bill

A couple of months ago I blogged about iterators in VB (or the lack there-of), and pointed folks to an article I wrote for Visual Studio magazine that provides snippets and templates to help with iterators in VB.

One of the things I talk about in that article is often the use of iterators in C# code that I have seen is superfulous, especially given the LINQ libraries.  Yesterday I read another example of this where the developer(s) had written a custom iterator instead of using a LINQ query. Their code required the defining of a generic class:

public class EnumerableGeneric<TClass, TInterface> 
              : IEnumerable<TInterface> where TClass : TInterface
{
   private IList<TClass> list;

   public EnumerableGeneric(IList<TClass> list)
   {
      this.list = list;
   }

   public IEnumerator<TInterface> GetEnumerator()
   {
      foreach (TClass item in list)
      {
         yield return item;
      }
   }

   IEnumerator IEnumerable.GetEnumerator()
   {
      return this.GetEnumerator();
   }
}

 

And the example of using this required the calling code to instantiate an instance of this class:

 

MyMethod(new EnumerableGeneric<ClassA, IClassInterface>(caInstance));

 

A simpler alternative is to actually use LINQ, eg:

      MyMethod(caInstance.Cast<IClassInterface>());

 

In VB talk I think it’s even more natural flowing:

    MyMethod(caInstance.Cast(Of IClassInterface))

 

It is in places like that I like the (Of T) syntax of VB a lot better, but some folks prefer a Cup<T> to a Cup(Of T)  .  The key point here is the use of “yield return” in C# is a good indicator that the code can often be replaced with far simpler LINQ constructs that reduce your LOC’s, and hence reduce your debugging and maintenance loads.  There will of course be times where there isn’t a simple LINQ replacement, but if you do ever come across custom iterators, do take pause to think about using LINQ.

Filed under: , , , ,