前に書いた記事の部分抜粋(C++)
main.cpp
#include <iostream>
#include <vector>
usingnamespacestd;voidPrint(vector<int>v){for(auto&i:v){cout<<" "<<i;}cout<<endl;}intmain(){vector<int>vkeep{5,5,0,5,1};//5個Print(v);cout<<"--- rfor内で自身のコンテナ追加 ------rforの値がバグる--------------"<<endl;for(auto&i:v){cout<<" "<<i;if(i==5)v.emplace_back(123);//v.push_back(123);}cout<<endl<<"-----5は3つあるので3つ123が増えないといけないが、バグっている-----"<<endl;Print(v);}
実行結果、イテレータの位置がおかしくなり、エラーでなくバグる << 仕様らしい(エラーにしてほしいが・・・)
実行結果 :要素数も増えていなくて値も -572662307 という表示になる
--- rfor内で自身のコンテナ追加 ------rforの値がバグる--------------
5 -572662307 -572662307 -572662307 -572662307
これのC#バージョンを作る、ついでにラムダ記述方法も忘れたので確認
結論から言うと、foreach内での自身の配列(List)に要素数を増やすとエラーになる。
下記では、別配列(List)を用意して一旦こちらに追加して、まとめて追加(AddRange)している
main.cs
usingSystem;usingSystem.Collections.Generic;namespaceConsoleApp1{classProgram{staticvoidMain(string[]args){Console.WriteLine("Hello World!");List<int>v=newList<int>(){5,5,0,5,1};varvpp=newList<int>();foreach(varainv){//if (a == 5) v.Add(123); //errorif(a==5)vpp.Add(123);}// ラムダで書いたバージョン//v.ForEach(a => { if (a == 5) v.Add(123); }); //error//v.ForEach(a => { if (a == 5) vpp.Add(123); });v.AddRange(vpp);// v配列に appデータを増やすforeach(varainv){Console.Write(" {0}",a);}// ラムダで書いたバージョン//v.ForEach(a =>{// Console.Write(" {0}",a);//});Console.WriteLine();}}}
実行結果
Hello World!
5 5 0 5 1 123 123 123
ちなみにエラーコメントの行のコメントを外してもビルドエラーは出ない。
C# ではforeach で自身配列の変更をしてはいけないとなっており、
実行するとエラーが foreach の行ですぐ出る。
C++では参照型を用い、rfor内の配列内の値の変更は可能だが、C#ではforeach 内ではそれすら許されない。
それは要素の増加に関しても同様のようだ。
※VS2010時のC#の古いバージョンでは、foreachでの自身の値の変更はできて便利だった・・・