RemoveAt() not working c#

Erick Azpeytia picture Erick Azpeytia · Oct 17, 2012 · Viewed 8.3k times · Source

Even after the RemoveAt() method, my list keeps being the same and I don't even get an error:

foreach (var row in queryCandidates.ToList())
{
    try
    {
        xString = queryCandidates.ToList().ElementAt(i).District;
        int.TryParse(xString, out xNumber);

        temp = xNumber.Equals(districtNumber);
        System.Diagnostics.Debug.Write(temp+ " ");
        System.Diagnostics.Debug.Write(i+" ");
        if (temp == false)
        {
            System.Diagnostics.Debug.WriteLine(" i is:"+i);

            //not working even when it should
            queryCandidates.ToList().RemoveAt(i);

        }
    }

    catch { }
    i++;
    if (last == i)
    {
        System.Diagnostics.Debug.WriteLine("before ending loop: ");
        return View(queryCandidates.ToList());
    }
}

System.Diagnostics.Debug.WriteLine("after ending the loop: ");
return View(queryCandidates.ToList());

Answer

Daniel Hilgarth picture Daniel Hilgarth · Oct 17, 2012

ToList() creates a new instance. From this instance you are removing the element. You are not removing the element from the original enumerable.

You should be doing something like this instead:

var candidates = queryCandidates.ToList();
var elementsToRemove = new List<int>();
foreach (var row in candidates)
{
    // ...
    xString = candidates[i].District;
    // ...
    if (temp == false)
    {             
        // ... 
        elementsToRemove.Add(i);
    }  
}

for(int i = elementsToRemove.Count - 1; i >= 0; --i)
    candidates.RemoveAt(elementsToRemove[i]);

return View(candidates);

Please note the use of elementsToRemove. You can't remove the items directly in the loop. This will throw an exception.


Additionally, please note that ToList copies all data. Every single time you call it. It should be obvious that this is not a good idea to do in a loop.