Это то, что я изучал, чтобы посмотреть, смогу ли я взять то, что было
List<MdiChild> openMdiChildren = new List<MdiChild>();
foreach(child in MdiManager.Pages)
{
openMdiChildren.Add(child);
}
foreach(child in openMdiChild)
{
child.Close();
}
и сократить его, чтобы не требовалось 2 foreach
петель.
Примечание Я изменил то, как называются объекты, чтобы упростить это для этого примера (они получены от сторонних элементов управления). Но для информации и понимания
MdiManager.Pages
наследует форму CollectionBase
, которая в свою очередь наследует IEnumerable
и MdiChild.Close()
удаляют открытый дочерний элемент из коллекции MdiManager.Pages
, изменяя таким образом коллекцию и вызывая при перечислении исключение, если коллекция была изменена во время перечисления, например.
foreach(child in MdiManage.Pages)
{
child.Close();
}
Я смог работать с двойным foreach
до
((IEnumerable) MdiManager.Pages).Cast<MdiChild>.ToList()
.ForEach(new Action<MdiChild>(c => c.Close());
Почему это не имеет те же проблемы, связанные с изменением коллекции во время перечисления? Мое лучшее предположение заключается в том, что при перечислении по списку, созданному с помощью вызова ToList, он фактически выполняет действия с соответствующим элементом в коллекции MdiManager.Pages
, а не сгенерированным списком.
Редактировать
Я хочу пояснить, что мой вопрос заключается в том, как я могу упростить это, я просто хотел понять, почему не было проблем с изменением коллекции, когда я выполнял ее так, как я ее написал в настоящее время.