Another LINQ puzzle

I was discussing the little LINQ puzzle with Stephen Toub, and he brought up an idea which lead to another puzzle. I like this one even more than the previous one.

Why does the last line throw StackOverflowException?

IEnumerable<int> q = new int[] { 1, 2 };
q = from x in new int[] { 1, 2 }
    from y in q
    select x + y;
q.ToArray();

And, how come the code sample runs just fine if you switch the order of the from clauses?

5 thoughts on “Another LINQ puzzle”

  1. @Scorcels: Here is a VB version of the puzzle.

    Dim q As IEnumerable(Of Integer) = Enumerable.Range(1, 2)
    q = From x In Enumerable.Range(1, 2) _
    From y In q _
    Select x + y
    q.ToArray()

  2. Because there is recursive enumeration of q (-> closure) which is more evident if you rewrite it as:

    q = new int[] { 1, 2 }.SelectMany(x => q, (x, y) => x + y);

    when ToArray is called q is defined as above.

    if you switch order there is no closure
    q.SelectMany(y => new int[] { 1, 2 }, (x, y) => x + y);

Leave a Comment