问题描述
我有一个代码
foreach (DataColumn dataTableCol in this.dataTable.Columns) { bool columnFound = false; foreach (GRTColumnView uiColumn in descriptor.UIColumns) { if (dataTableCol.ColumnName.Equals(uiColumn.Name)) { columnFound = true; break; } } if (!columnFound) { if (this.dataTable.Columns.Contains(dataTableCol.ColumnName)) this.dataTable.Columns.Remove(dataTableCol.ColumnName); } }
如果在另一个集合中找不到,我想从集合中删除一些"东西".
当我运行上述程序时,我会得到
迭代可能不会执行,因为修改了收集
"收集被修改" - coz删除必须被击中
那么,实现此类事物的方法是什么?
我能想到的是记下所有要删除的"事物",然后
foreach( aThing in all_things_to_remove) remove_from_collection(aThing)
,但以上似乎不是我的好方法,因为我必须做另一个循环并使用额外的内存
推荐答案
在这种特定情况下,您要通过包含几列的小集合来循环,您可以创建一个新集合(通过ToList()),这样您就不会在同一集合上迭代您正在修改:
foreach (var dataTableCol in dataTable.Columns.Cast<DataColumn>().ToList()) { ... dataTable.Columns.Remove(dataTableCol.ColumnName); }
推荐的方式,尤其是在收藏很大的情况下,是向后枚举:
for (var i = dataTable.Columns.Count - 1; i >= 0; i--) { ... dataTable.Columns.Remove(dataTable.Columns[i].ColumnName); }
其他推荐答案
在用foreach循环列举其时,您不能从集合中删除项目.使用Collection.ToArray()制作集合的副本,然后在副本上运行foreach,然后从实际集合中删除您的项目.
因为datatable.columns没有ToArray或ToList方法,您可以使用CopyTo()方法并将整个列复制到列.
如果您不想创建副本,则可以用于循环而不是foreach循环.您可以以这种方式编辑编码:
for (int i = 0; i < dataTable.Columns.Count; i++) { bool columnFound = false; foreach (GRTColumnView uiColumn in descriptor.UIColumns) { if (dataTable.Columns[i].Name.Equals(uiColumn.Name)) { columnFound = true; break; } } if (!columnFound) { if (this.dataTable.Columns.Contains(dataTableCol.ColumnName)) this.dataTable.Columns.Remove(dataTableCol.ColumnName); } }
其他推荐答案
另一种方法是在删除列后降低索引.
for (int i = 0; i < datatable.Columns.Count; i++) { if (datatable.Columns[i].ColumnName.Contains("Column")) { datatable.Columns.RemoveAt(i); i--; } }