This is an interesting error I’ve come across while implementing IEnumerable on a class. It appears to be similar to an “access to modified closure” issue, but I’m at a loss as to how to fix it.
Here is a simple example that demonstrates the issue:
void Main()
{
var nodeCollection = new NodeCollection();
nodeCollection.MyItems = new List<string>() { "a", "b", "c" };
foreach (var node in nodeCollection)
{
node.Dump();
}
}
public class NodeCollection : IEnumerable<Node>
{
public List<string> MyItems;
public IEnumerator<Node> GetEnumerator()
{
// This isn't necessary, but it should prove that it's not an "access to modified closure" issue.
var items = MyItems;
for (var i = 0; i < 3; i++)
{
var node = new Node();
// I want the node to contains the items in MyItems.
node.Items = items;
// Plus an additional item. Note that I am adding the item to the node, NOT to MyItems.
node.Items.Add(string.Format("iteration: {0}", i));
yield return node;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Node
{
public List<string> Items;
}
As you can see from the Dump() statement, I’m running this in LINQPad, but the issue will present itself in any IDE.
When I run the snippet, I get the following output:

Because I am adding the item to Items in the newly instantiated Node, I would NOT expect the item to be added to MyItems, but this is obviously what is occurring.
It seems that Items in Node is pointing to MyItems in NodeCollection.
Can anyone tell me:
- Why this is happening?
- How to make it not happen?
You are creating new nodes each iteration, but then setting the same
itemsinstance to theItemsproperty of each node. Then you are adding the iteration string to the items instance stored in the Items collection (which is always the same instance), resulting in each subsequent node having more and more “iteration” entries. If you kept all of the nodes, you’d find that all of them have exactly the sameItemsvalue.I think the basic misunderstanding here was that you were assuming that setting the Items property of the Node (
node.Items = items;) would copy theitemslist into the node. In fact, all it does is set node.Items to point to the already-existing list that you callitems.This should give you an idea where you went wrong: