Collection was modified の原因と直し方
foreach中にList等のコレクションの要素数を変えると発生します。反復子(イテレータ)が内部状態の不整合を検知する仕組みです。
エラーメッセージの読み方
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
System- 名前空間 — System なら標準の基本例外です
InvalidOperationException- 例外クラス — 何が起きたか。ここを検索するのが最短です
Collection was modified; enumeration operation may not execute.- 詳細メッセージ — どの値が問題だったか
at Program.Main(String[] args) in Program.cs:line 4- 発生箇所 — スタックトレースの先頭行
このエラーが出る典型パターン
パターン1
1 class Program { 2 static void Main(string[] args) { 3 var nums = new System.Collections.Generic.List<int> { 1, 2, 3 }; 4 foreach (int n in nums) { 5 if (n == 2) { 6 nums.Remove(n) ; ^ 7 } 8 } 9 } 10 }
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at Program.Main(String[] args) in Program.cs:line 4
foreach中にコレクションの要素数を変えると、内部の反復子が不整合を検知して例外を投げます。
直し方: nums.Remove(n) を System.Console.WriteLine(n) にします。
広告
広告スロット(未設定)
パターン2
1 class Program { 2 static void Main(string[] args) { 3 var nums = new System.Collections.Generic.List<int> { 1, 2, 3 }; 4 foreach (int n in nums) { 5 if (n == 1) { 6 nums.Add(n * 10) ; ^ 7 } 8 } 9 } 10 }
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at Program.Main(String[] args) in Program.cs:line 4
要素を追加する場合も同じです。反復中はコレクションの形を変えてはいけません。
直し方: nums.Add(n * 10) を System.Console.WriteLine(n * 10) にします。
パターン3
1 class Program { 2 static void Main(string[] args) { 3 var nums = new System.Collections.Generic.List<int> { 1, 2, 3 }; 4 foreach (int n in nums) { 5 if (n == 3) { 6 nums.RemoveAt(0) ; ^ 7 } 8 } 9 } 10 }
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at Program.Main(String[] args) in Program.cs:line 4
RemoveAtでインデックス指定で消す場合も同様です。安全に消したいならToList()でコピーしてから反復します。
直し方: nums.RemoveAt(0) を System.Console.WriteLine(nums[0]) にします。
よくある誤解
forループなら添字で直接アクセスするので気づきにくいですが、foreachは内部で反復子を使っており、反復中の追加・削除に非常に敏感です。
まとめ
Collection was modifiedは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。