Brendan Enrick

Daily Software Development

Foreach, IEnumerable, IEnumerator, and Duck Typing

During my Software Craftsmanship Precompiler session, I heard one of the students say, “all you need is an IEnumerable to use a foreach loop”. This sparked a bit of fun when I asked Steve Smith, my co-presenter, if that was correct. He confirmed that it was, and I disagreed. Being the scientists that we are, we decided to try it and see what happened. I of course knew that duck typing in C# should allow the Foreach loop to compile without anything having the method required by the IEnumerable interface. This means that we just need a GetEnumerator method.

We wrote the code that did this and it compiled!

Duck typing is awesome, because it allows the language to treat my type the way I want it to because it has the right tools to do the job. The term duck typing comes from the idea that if it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

In the foreach loop example, duck typing assumes that what you have here is able to be enumerated, because it has a method to get the enumerator. If we look at the IEnumerable interface, we can see that this is what we are required to implement.

public class MyCollection : IEnumerable
{
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}

Now that we have our collection written and implementing IEnumerable, we can write a foreach loop that uses our collection.

var myCollection = new MyCollection();
foreach (var thing in myCollection)
{
// Do something with the thing
}

Finally, because of the duck typing in C#, we can remove the interface from the code, but keep the method.

public class MyCollection
{
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}

It still compiles!

One of the many cool things about C# that I love. It’s a fun language, so go experimenting!

Comments (5) -

  • Daniel White

    1/27/2012 12:37:35 PM | Reply

    According to the Jan 2012 MSDN magazine, it even works with LINQ syntax.

  • Brendan Enrick

    1/30/2012 11:14:39 AM | Reply

    @Daniel You are correct, sir, I just grabbed a copy of the magazine and found the LINQ reference you mentioned. I found it in Ted Neward's article. It doesn't mention duck typing specifically, but it does mention that LINQ is using method signatures to check if the object has Select, SelectMany, Where, etc. to decide if it is able to be used by LINQ. Isn't it cool how many places this actually comes up?

    When I mentioned this out in my team room here, one of my coworkers also mentioned that he once read a blog post where someone had some fun making those methods do tasks other than what they're supposed to do and using the class with LINQ. I will have to inquire further about this and see what was done or just try it myself.

  • Chris

    2/16/2012 7:49:29 AM | Reply

    Interesting indeed! I had no idea you could do this.

  • Lukasz Anforowicz

    4/18/2012 3:55:59 PM | Reply

    Unfortunately it doesn't seem to work if GetEnumerator is an extension method :-(

Loading