1

我有一个代码

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);
                }

            }

如果在另一个集合中找不到它们,我想从集合中删除一些“东西”。

当我运行上述程序时,我得到

修改集合时可能无法执行迭代

“收藏已修改” - 因为删除必须已被击中

那么有什么方法可以实现这样的事情呢?

我能想到的是记下所有要删除的“东西”,然后

foreach( aThing in all_things_to_remove)
     remove_from_collection(aThing)

但上面对我来说似乎不是一个好方法,因为我必须做另一个循环并且正在使用额外的内存

4

4 回答 4

5

在这种特定情况下,您正在循环一个包含几列的小集合,您可以创建一个新集合(通过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);
}
于 2015-01-14T02:44:37.593 回答
0

在使用 foreach 循环枚举集合时,您不能从集合中删除项目。使用复制集合Collection.ToArray()并在副本上运行 foreach 并从实际集合中删除您的项目。

由于 DataTable.Columns 没有 ToArrayorToList方法,您可以使用该CopyTo()方法并将整个列复制到 ColumnsArray。

如果您不想创建副本,则可以使用 for 循环而不是 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);
    }

}
于 2015-01-14T02:44:00.790 回答
0
if (dt.Columns.Contains("RecordID")){
                    dt.Columns.Remove("RecordID");
                    dt.AcceptChanges();
                }
于 2019-05-07T18:59:24.793 回答
0

另一种方法是在删除列后降低索引。

for (int i = 0; i < datatable.Columns.Count; i++)
            {
                if (datatable.Columns[i].ColumnName.Contains("Column"))
                {
                    datatable.Columns.RemoveAt(i);
                    i--;
                }
            }
于 2018-02-28T14:17:29.350 回答