Removing items from a list when a condition is met

10,728

Solution 1

List<T> has a method

public int RemoveAll(
    Predicate<T> match
)

that removes all elements matching a predicate: http://msdn.microsoft.com/en-us/library/wdka673a.aspx

Therefore I suggest something like:

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

(note that == true is not needed since .queryComplete() already returns true or false!)

Solution 2

Iterate backwards in a For loop instead of a Foreach loop

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);
    }
}

Solution 3

Patashu's answer is the best solution in general, but based on your example code I would suggest taking another approach altogether.

Are you polling the download list periodically to find the completed ones? Event subscription would probably be a better solution. Since you're new to C#, in case you didn't know the language has built-in support for this pattern: Events

A download could raise a Completed event when it completes, which is subscribed to by the code which manages the list, something like:

private void AddDownload(DownloadOperation dl) {
    download.Add(dl);
    dl.Completed += (s, e) => download.Remove(dl);
}
Share:
10,728
Admin
Author by

Admin

Updated on June 24, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm writing a multi-threaded download manager where download info is managed by a class I wrote (called DownloadOperation). Downloads are held in a list (called download). I need to remove the objects from the list when a function in the class (queryCompleted) returns true but found out that elements could not be removed from lists from within a foreach loop. What is the best way to have the same effect? I'm relatively new to C# so pardon my stupidity.

    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);
                }
            }
        }