Brendan Enrick's Blog

Daily Software Development.


Foreach, IEnumerable, IEnumerator, and Duck Typing

by Brendan Enrick Friday, January 27 2012 10:00

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

1/27/2012 12:37:35 PM #

Daniel White

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

Daniel White United States

1/30/2012 11:14:39 AM #

Brendan Enrick

@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.

Brendan Enrick United States

2/1/2012 1:51:03 PM #

trackback

Fun with IL DASM and Duck Typing

Fun with IL DASM and Duck Typing

Brendan Enrick

2/16/2012 4:36:20 AM #

pingback

Pingback from blog.cwa.me.uk

The Morning Brew - Chris Alcock  » The Morning Brew #1045

blog.cwa.me.uk

2/16/2012 7:49:29 AM #

Chris

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

Chris United Kingdom

2/16/2012 1:12:19 PM #

alastair

Eric Lippert has a good post about this and why they used a pattern based approach *in this specific case*

blogs.msdn.com/.../following-the-pattern.aspx

alastair United Kingdom

4/18/2012 3:55:59 PM #

Lukasz Anforowicz

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

Lukasz Anforowicz United States

Comments are closed