【问题标题】:how to remove an item from class list while using for-each loop? [duplicate]使用for-each循环时如何从类列表中删除一个项目? [复制]
【发布时间】:2017-03-13 14:47:19
【问题描述】:

我在下面调用这个函数,类列表有 3 到 4 个列表项,在 foreach 循环中,我将系统时间与设定时间进行比较,如果系统时间超过它们,我通过调用从 PIR_ConditionList 中删除该特定列表:

PIR_ConditionList.RemoveAll(element => element == Li);

但我得到了错误:

集合已修改;枚举操作可能无法执行。删除列表项

我推断这是 foreach 中的错误,因为您无法在循环中删除项目。有没有其他方法或解决方案。

Task.Factory.StartNew(() =>
            {
                try
                {
                    while (PIR_ConditionList.Count>0)
                    {

                        foreach (var Li in PIR_ConditionList)
                        {
                            if (Li.dateimePresent < Li.datetimePlusFour)
                            {
                                var dimLevel = Li.dimLevel;
                                AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
                                Li.dateimePresent = DateTime.Now;
                                Thread.Sleep(10000);
                            }
                            else
                            {

                                PIR_ConditionList.RemoveAll(element => element == Li);

                            }
                        }

                    }
                }
                catch (Exception ee)
                {
                    fourMinTimer();
                }
            }); 

【问题讨论】:

  • 改用for,你不能修改foreach中的集合。
  • 亚历山德罗所说的。在foreach 中,您只能修改集合的属性,但不能修改集合本身。
  • for 循环会起作用吗?如何在 for 循环中删除项目?
  • 提示:尝试谷歌搜索异常文本本身。这种技术需要能够缩小搜索结果(添加/删除/忽略某些词),因此掌握它并不容易,但会非常有用。

标签: c# list foreach


【解决方案1】:

您可以使用向后的for-loop + List.RemoveAt:

for(int i = PIR_ConditionList.Count -1 ; i >= 0; i--)
{
    var Li = PIR_ConditionList[i];
    if (Li.dateimePresent < Li.datetimePlusFour)
    {
        var dimLevel = Li.dimLevel;
        AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
        Li.dateimePresent = DateTime.Now;
        Thread.Sleep(10000);
    }
    else
        PIR_ConditionList.RemoveAt(i);
}

但由于您使用的是多个线程,请注意List&lt;T&gt; 不是线程安全的。

【讨论】:

    【解决方案2】:

    你必须使用for循环:

    for (var i = 0; i< PIR_ConditionList.Count; i++)
    {
        var Li = PIR_ConditionList[0];
    
        if (Li.dateimePresent < Li.datetimePlusFour)
        {
            var dimLevel = Li.dimLevel;
            AcquisitionLoop.Luminaires.EnqueueCommand(new SetDimLVLNEW(new SetBrightnessNEW(Li.lumId, dimLevel, Li.lumNumId, Li.clusterId)));
            Li.dateimePresent = DateTime.Now;
            Thread.Sleep(10000);
        }
        else
        {
            PIR_ConditionList.RemoveAt(i);
    
            i--;
        }
    }
    

    试试这个代码。

    【讨论】:

      猜你喜欢
      • 2013-10-15
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 2016-09-07
      • 2011-01-04
      • 2012-01-08
      相关资源
      最近更新 更多