问题
I have a code
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);
}
}
I want to remove some "things" from collection if they aren't found in another collection.
When I run the above program, I get
Iteration may not execute as collection was modified
"Collection was modified" - Coz the remove must have been hit
What is the way to achieve such a thing then ?
What I can think of is make a note of all the "things" to remove and then
foreach( aThing in all_things_to_remove)
remove_from_collection(aThing)
But above doesn't seem a good way to me, as I have to do another looping and am using extra memory
回答1:
In this specific case, where you're looping through a small collection containing a few columns, you can just create a new collection (via ToList()
), so that you're not iterating over the same collection you're modifying:
foreach (var dataTableCol in dataTable.Columns.Cast<DataColumn>().ToList())
{
...
dataTable.Columns.Remove(dataTableCol.ColumnName);
}
The recommended way, especially if the collection is large, is to enumerate backwards:
for (var i = dataTable.Columns.Count - 1; i >= 0; i--)
{
...
dataTable.Columns.Remove(dataTable.Columns[i].ColumnName);
}
回答2:
You cannot remove items from a collection while enumerating it with the foreach loop. Make a copy of the collection using Collection.ToArray()
and run you foreach on the copy and remove your item from the actual collection.
Since DataTable.Columns does not have ToArray
or ToList
methods, you could use the CopyTo()
method and copy the entire columns to a ColumnsArray.
If you do not want to create a copy, then you can use for loop instead of foreach loop. You could edit you code this way:
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);
}
}
回答3:
the other way is lowering the index after removing column.
for (int i = 0; i < datatable.Columns.Count; i++)
{
if (datatable.Columns[i].ColumnName.Contains("Column"))
{
datatable.Columns.RemoveAt(i);
i--;
}
}
回答4:
if (dt.Columns.Contains("RecordID")){
dt.Columns.Remove("RecordID");
dt.AcceptChanges();
}
来源:https://stackoverflow.com/questions/27934943/how-to-remove-datacolumn-from-datatable-programmatically