【问题标题】:Problem removing row in datatable while enumerating枚举时删除数据表中的行的问题
【发布时间】:2010-12-15 16:38:59
【问题描述】:

当我尝试在循环中删除一行时出现以下错误。

C#:集合已修改;枚举操作可能无法执行

我已经做了一段时间的研究,我也在这里阅读了一些类似的帖子,但我仍然没有找到正确的答案。

foreach (DataTable table in JobsDS.Tables)
{

  foreach (DataRow row in table.Rows)
  {
    if (row["IP"].ToString() != null && row["IP"].ToString() != "cancelled")
    {
        string newWebServiceUrl = "http://" + row["IP"].ToString() + "/mp/Service.asmx";
        webService.Url = newWebServiceUrl;
        string polledMessage = webService.mpMethod(row["IP"].ToString(), row["ID"].ToString());

        if (polledMessage != null)
        {
            if (polledMessage == "stored")
            {               
                removeJob(id);
            }

        }
    }
}

}

任何帮助将不胜感激

【问题讨论】:

    标签: c# datatable


    【解决方案1】:

    不要使用foreach,而是使用反向for循环:

    for(int i = table.Rows.Count - 1; i >= 0; i--)
    {
        DataRow row = table.Rows[i];
        //do your stuff
    }
    

    删除该行确实会修改原始行集合。大多数枚举器被设计为在枚举过程中检测到源序列发生变化时爆炸——而不是尝试处理 foreaching 的所有奇怪可能性,因为它们正在发生变化并可能引入非常微妙的错误,它更安全简单地禁止它。

    【讨论】:

      【解决方案2】:

      您不能在 foreach 周围修改集合。

      相反,您应该使用向后的for 循环。

      【讨论】:

        【解决方案3】:

        如果你想从元素列表的循环中删除元素,诀窍是使用 for 循环,从最后一个元素开始并转到第一个元素。

        在你的例子中:

        int t_size = table.Rows.Count -1;
        
        for (int i = t_size; i >= 0; i--)
        {
           DataRow row = table.Rows[i];
           // your code ...
        }
        

        编辑:不够快:)

        【讨论】:

        • @SLaks 我不认为它比你的评论有更多或更少的意义
        【解决方案4】:

        此外,如果您依赖于处理行的顺序并且反向循环对您不起作用。您可以将要删除的行添加到列表中,然后在退出 foreach 循环后,您可以删除添加到列表中的行。例如,

        foreach (DataTable table in JobsDS.Tables) 
        { 
          List<DataRow> rowsToRemove = new List<DataRow>();
          foreach (DataRow row in table.Rows) 
          { 
            if (row["IP"].ToString() != null && row["IP"].ToString() != "cancelled") 
            { 
                string newWebServiceUrl = "http://" + row["IP"].ToString() + "/mp/Service.asmx"; 
                webService.Url = newWebServiceUrl; 
                string polledMessage = webService.mpMethod(row["IP"].ToString(), row["ID"].ToString()); 
        
                if (polledMessage != null) 
                { 
                    if (polledMessage == "stored") 
                    {                
                        //removeJob(id); 
                        rowsToRemove.Add(row);
                    } 
        
                } 
            } 
          }
          rowsToRemove.ForEach(r => removeJob(r["ID"].ToString()));
        } 
        

        【讨论】:

          【解决方案5】:

          removeJob(id) 以某种方式更改了您枚举的 IEnumerable 之一(table.RowsJobsDS.Tables,从方法的名称来看,我猜是后者),可能是通过 DataBinding。

          我不确定向后的for 是否会直接起作用,因为您似乎正在从内部 foreach 中删除外部 foreach 中枚举的元素。如果没有关于 removeJob(id) 中发生的事情的更多信息,很难判断。

          【讨论】:

            猜你喜欢
            • 2016-07-21
            • 2011-05-10
            • 1970-01-01
            • 2021-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多