我必须从数据表中删除一些行.我听说在迭代它时改变一个集合是不行的.因此,我不是检查一行是否满足删除要求然后将其标记为已删除的for循环,而应首先遍历数据表并在列表中添加所有行,然后遍历列表并标记删除行.这是什么原因,我有什么替代品(而不是使用我的意思的行列表)?
迭代后退通过列表听起来像一个更好的方法,因为如果你删除一个元素和其他元素"落入差距",这没关系,因为你已经看过那些.此外,您不必担心您的计数器变量变得大于.Count.
Listtest = new List (); test.Add(1); test.Add(2); test.Add(3); test.Add(4); test.Add(5); test.Add(6); test.Add(7); test.Add(8); for (int i = test.Count-1; i > -1; i--) { if(someCondition){ test.RemoveAt(i); } }
拿@bruno代码,我会倒退.
因为当您向后移动时,缺少的数组索引不会干扰循环的顺序.
var l = new List(new int[] { 0, 1, 2, 3, 4, 5, 6 }); for (int i = l.Count - 1; i >= 0; i--) if (l[i] % 2 == 0) l.RemoveAt(i); foreach (var i in l) { Console.WriteLine(i); }
但是,如今,我会使用LINQ:
var l = new List(new int[] { 0, 1, 2, 3, 4, 5, 6 }); l.RemoveAll(n => n % 2 == 0);
如果使用简单for
循环,则可以从集合中删除元素.
看看这个例子:
var l = new List(); l.Add(0); l.Add(1); l.Add(2); l.Add(3); l.Add(4); l.Add(5); l.Add(6); for (int i = 0; i < l.Count; i++) { if (l[i] % 2 == 0) { l.RemoveAt(i); i--; } } foreach (var i in l) { Console.WriteLine(i); }
由于您正在使用DataTable并且需要能够使用表适配器将任何更改保留回服务器(请参阅注释),以下是如何删除行的示例:
DataTable dt; // remove all rows where the last name starts with "B" foreach (DataRow row in dt.Rows) { if (row["LASTNAME"].ToString().StartsWith("B")) { // mark the row for deletion: row.Delete(); } }
在行上调用delete会将其RowState属性更改为Deleted,但会将已删除的行保留在表中.如果在将更改保存到服务器之前仍然需要使用此表(如果要显示表的内容减去已删除的行),则需要在迭代时检查每行的RowState,如下所示:
foreach (DataRow row in dt.Rows) { if (row.RowState != DataRowState.Deleted) { // this row has not been deleted - go ahead and show it } }
从集合中删除行(如bruno的答案)将破坏表适配器,通常不应该使用DataTable.