views:

463

answers:

6

I dont understand why I cannot do the below - This should work??

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}
A: 

The Rows content changes while you are iterating if you delete one row, which renders the iteration invalid.

You can, however, copy the rows into a collection first and then iterate over the collection and delete the rows that way. This makes sure that the iteration is not interrupted by changing data to be iterated.

Lucero
How do I do that exactly?
ChloeRadshaw
+8  A: 

Most collections in .NET don't allow you to change the contents of the collection while you're iterating over it. From the docs for IEnumerator:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException. If the collection is modified between MoveNext and Current, Current returns the element that it is set to, even if the enumerator is already invalidated.

The best solution is usually to create a separate collection (e.g. a List<DataRow>) of items you want to remove, and then remove them after you've finished iterating.

Jon Skeet
A: 

This applies to pretty much any collection. If you try to delete an item while looping through the collection, you will have a problem. For example, if you delete row #3, then the previous row #4 becomes row #3.

DOK
+5  A: 

You cannot modify a collection while you're iterating on it using a foreach statement.

you can try something like that :

List<DataRow> deletedRows = new List<DataRow>();

foreach (DataRow dataRow in dataTable.Rows)
{
    if(true) deletedRows.Add(dataRow);
}

foreach(DataRow dataRow in deletedRows)
{
    dataRow.Delete();
}
Thibault Falise
Incorrect. You cannot modify a collection while iterating through it with a "foreach" You can use a standard 'for' loop. eg: `for(int i = datatable.Rows.length - 1; i >= 0; i --) { //remove rows }`
AllenG
@AllenG : Thanks, I added the info.
Thibault Falise
Deletion is possible while iteration is on http://stackoverflow.com/questions/3150216/data-table-delete-a-row-in-c-using-loop
fzshah76
@fzshah76 : No, in your example, using the `Select()` method creates a new collection containing all rows of the previous collection. You are not iterating on the original collection, which contains the row you are deleting.
Thibault Falise
@ Thibault Falise: Thanks for clarifying :)
fzshah76
A: 

Use this:

for (int i = 0; i < myDataTable.Rows.Count; i++)

{

myDataTable[i].Delete();

}

1111
You actually want to do this the other way `(int i - mydatatable.rows.count -1; i >= 0; i--)` Your way can lead to rows being skipped (and, in my experience, usually does.
AllenG
A: 

Safest way - use for loop

for (int i = datatable.Rows.length - 1; i >= 0; i--) 
{
    if (true)
    {
        dataRow.Delete();
    }
}
VMAtm