满足条件时从列表中删除项目

时间:2013-07-02 23:37:31

标签: c# .net list class foreach

我正在编写一个多线程下载管理器,其中下载信息由我编写的类(称为DownloadOperation)管理。下载保存在列表中(称为下载)。我需要在类(queryCompleted)中的函数返回true时从列表中删除对象,但发现无法从foreach循环中的列表中删除元素。获得相同效果的最佳方法是什么?我对C#比较新,所以请原谅我的愚蠢。

private void removeInactiveDownloads()
    {
        foreach (DownloadOperation dl in download)
        {
            if (dl.queryComplete() == true)
            {
                // if download is no longer in progress it is removed from the list.
                download.Remove(dl);
            }
        }
    }

编辑 - 更正了示例代码中的错误。

3 个答案:

答案 0 :(得分:11)

List<T>有一个方法

public int RemoveAll(
    Predicate<T> match
)

删除与谓词匹配的所有元素:http://msdn.microsoft.com/en-us/library/wdka673a.aspx

因此我建议如下:

download.RemoveAll(x => x.queryComplete());

(请注意,由于== true已经返回true或false,因此不需要.queryComplete()。)

答案 1 :(得分:3)

在For循环中向后迭代而不是Foreach循环

for(int i = download.Count; i >= 0; i--)
{
    if (download[i].queryComplete())
    {
       // if download is no longer in progress it is removed from the list.
       download.RemoveAt(i);
    }
}

答案 2 :(得分:1)

Patashu的回答是一般的最佳解决方案,但根据您的示例代码,我建议完全采用另一种方法。

您是否定期轮询下载列表以查找已完成的下载列表?事件订阅可能是更好的解决方案。由于您不熟悉C#,如果您不知道该语言对此模式有内置支持:Events

下载可能会在完成时引发Completed事件,该事件由管理列表的代码订阅,如:

private void AddDownload(DownloadOperation dl) {
    download.Add(dl);
    dl.Completed += (s, e) => download.Remove(dl);
}