C#でListの要素を削除するコードを書いて実行したところInvalidOperationExceptionが発生した。
最初は原因がわからなかったが、foreachの途中でListの要素を削除したことによってループを継続することができなくなったようだ。
C#
[csharp]
try
{
List<String> list = new List<string>();
list.Add("OK");
list.Add("OK");
list.Add("NG");
list.Add("OK");
foreach (String str in list) {
if (str == "NG") {
list.Remove(str);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.ReadLine();
}
[/csharp]
出力結果
場所 System.Collections.Generic.List`1.Enumerator.MoveNextRare()
場所 System.Collections.Generic.List`1.Enumerator.MoveNext()
場所 TestCSharp.Program.Main(String[] args)
IEnumeratorインターフェースのmoveNextを利用してループしても同様の結果となった。
ループの途中でListの要素を削除するには以下のようにindex指定でアクセスする必要がある。
[csharp]
List<String> list = new List<string>();
list.Add("OK");
list.Add("OK");
list.Add("NG");
list.Add("OK");
for (int i = 0; i < list.Count; i++ )
{
if (list[i] == "NG") {
list.RemoveAt(i);
}
}
foreach (String str in list) {
Console.WriteLine(str);
}
[/csharp]
OK
OK
ちなみにJavaならIteratorでも問題なく削除できる。
[java]
List<String> list = new ArrayList<String>();
list.add("OK");
list.add("OK");
list.add("NG");
list.add("OK");
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
if (itr.next().equals("NG")) {
itr.remove();
}
}
System.out.println(list.toString());
[/java]
出力結果
言語が変わると思わぬ動作の違いに驚いたりしますね。