C# InvalidOperationException

Exception

An InvalidOperationException has occurred. It reports a "collection was modified" error in the program. You have a collection such as a TreeView. You are removing items such as TreeNode controls in a foreach-loop.

Collections

Example

First let's examine some situations that can cause this exception, and then some ways to fix it. The example below demonstrates a TreeNodeCollection and a foreach loop that tries to remove an item, but raises an exception.

TreeView
Based on:

.NET 4.0

Code that causes exception: C#

foreach (TreeNode treeNode in treeView1.Nodes)
{
    if (treeNode.Nodes.Count == 0)
    {
	treeNode.Remove();
    }
}

Exception output

System.InvalidOperationException was unhandled
  Message="Collection was modified; enumeration operation may not execute."
  Source="mscorlib"
  StackTrace:
       at System.ThrowHelper.ThrowInvalidOperationException(...)
       at System.Collections.Generic.List`1.Enumerator.MoveNext()
Squares

In this example, we use the Nodes property on the TreeNode type. This returns a collection of TreeNode objects that are nested in the TreeView. The foreach-loop iterates over each item in the Nodes collection.

Then:We call the Remove method, and it tries to modify the collection during the loop.

Error. The important part of the InvalidOperationException means is the Message property. The Message on the second line is the secret we need to know. The message says "Collection was modified" and that the enumeration won't work.

Note:We are changing the elements in the collection while looping over it with foreach.

Foreach loop construct

Foreach queries the enumerator and asks for the next element. In our example, the enumerator's state becomes invalid when we remove the item. An enumerator has to store some data indicating where its current position.

Foreach

Example 2

Programming tip

Next, we fix the problematic code with some changes. This problem often occurs in Windows Forms control collections. I was puzzled by it when trying to remove nodes from a TreeView control.

Next:We see code that accomplishes the goal in the first example, without raising an exception.

Note:The TreeNode type has a Remove method. This is not the same syntax as Remove on a List.

TreeNode.Remove Method: MSDN
Code that fixes exception: C#

List<TreeNode> treeList = new List<TreeNode>();
foreach (TreeNode treeNode in treeView1.Nodes)
{
    if (treeNode.Nodes.Count == 0)
    {
	treeList.Add(treeNode);
    }
}

foreach (TreeNode treeNode in treeList)
{
    treeNode.Remove();
}

In this example, we store a List of TreeNode objects separately. We built this up with the TreeNode controls that we wish to remove. We want to remove TreeNode controls with no children. It is just solid, working code—the best kind.

List

Summary

C# programming language

By itself, an InvalidOperationException is not useful, but the "collection was modified" error message can be helpful. To remove items from a collection, first add references to all the objects you want to remove in a new List.

Then:Remove those items when iterating over the temporary collection. This depends on the collection type.


C#: Exception