Geeks With Blogs
Works on my machine

If you see IEnumerable<T> as read only collection crippled brother, this post is for you.

Many times I found myself loosing couple of hours looking for a bug everywhere, but not in a place where it was. From time to time the bug is caused by my simplified perception of IEnumerable. The thing is, if we do not know the mechanism that serves specific IEnumerable elements, we cannot be sure that each iteration will return equal collections with same objects.

It is not a big deal if it hosts immutable objects. With mutable however, we must be careful.

Let’s analyze following properties:

public static IEnumerable<StringBuilder> ByArray
{
    get
    {
        return new StringBuilder[] { new StringBuilder("foo") };
    }
}

public static IEnumerable<StringBuilder> ByYield
{
    get
    {
        yield return new StringBuilder("foo");
    }
}

and code that operates on them:

var enumerable = ByArray;
enumerable.First()[0] = 'b';
Console.WriteLine(enumerable.First());

enumerable = ByYield;
enumerable.First()[0] = 'b';
Console.WriteLine(enumerable.First());

This will write 2 lines. Can you predict each of them ? If not, I strongly advise you to run the code.

But that is not all. Analyze those two properties:

public static IEnumerable<StringBuilder> ByDynamicArray
{
    get
    {
        return new StringBuilder[] { new StringBuilder("foo") };
    }
}

public static IEnumerable<StringBuilder> ByStaticArray
{
    get
    {
        return fooArray;
    }
}

private static StringBuilder[] fooArray =
    new StringBuilder[] { new StringBuilder("foo") };

and their usage:

ByDynamicArray.First()[0] = 'b';
Console.WriteLine(ByDynamicArray.First());

ByStaticArray.First()[0] = 'b';
Console.WriteLine(ByStaticArray.First());

Notice that now we are operating directly on property, not on a local variable like in previous example. This is also important and can cause different output.

So be careful and think twice before writing code that operates on IEnumerable<T>.

Posted on Wednesday, October 31, 2012 12:23 AM | Back to top


Comments on this post: Beware the IEnumerable<T>

# re: Beware the IEnumerable<T>
Requesting Gravatar...
Nice stuff, it kind of make sense if you understand how yield works internally.
Left by buylar on Mar 06, 2013 7:44 AM

# re: Beware the IEnumerable<T>
Requesting Gravatar...
Thanks. You can read more about IEnumerable here:
http://csharpindepth.com/articles/chapter6/iteratorblockimplementation.aspx
Left by nabuk on Mar 06, 2013 9:39 AM

Your comment:
 (will show your gravatar)


Copyright © Jakub Niemyjski | Powered by: GeeksWithBlogs.net | Join free