linqクエリがあり、その結果をforeachループで繰り返します。
1つ目は、テーブルレイアウトパネルからコントロールのコレクションを取得するクエリです。次に、コレクションを繰り返し処理して、tableLayoutPanelからコントロールを削除します。
var AllItems = (from Item in this.tableLayoutPanel1.Controls.OfType<ItemControl>()
select Item);
foreach (ItemControl item in AllItems)
{
Trace.WriteLine("Removing " + item.ToString());
this.tableLayoutPanel1.Controls.Remove(item);
item.Dispose();
}
上記は私が期待したようには機能しません(つまり、エラーをスローします)、コントロールの半分(ODD番号が付けられたもの)だけを削除します。各反復でAllItemsはそれ自体を減らし、基になるコレクションは変更されていますが、エラーはありません。投げられた。
文字列の配列を使用してsimmilarを実行する場合:
string[] strs = { "d", "c", "A", "b" };
List<string> stringList = strs.ToList();
var allitems = from letter in stringList
select letter;
foreach (string let in allitems)
{
stringList.Remove(let);
}
今回、Visual Studioは、基になるコレクションが変更されたことを示すエラーを(予想どおりに)スローします。
なぜ最初の例も爆発しないのですか?
Iterators / IEnumerableには、ここでは理解できないことがあります。linqとforeachの内部で何が起こっているのかを誰かが理解するのを手伝ってくれるのではないかと思います。
(私は、反復する前にAllItems.ToList();によって両方の問題を解決できることを認識していますが、2番目の例がエラーをスローし、最初の例がエラーをスローしない理由を理解したいと思います)