【问题标题】:RemoveAt() not working c#RemoveAt()不起作用c#
【发布时间】:2012-10-07 22:27:20
【问题描述】:

即使在RemoveAt() 方法之后,我的列表仍然保持不变,我什至没有收到错误:

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

【问题讨论】:

  • 那里有很多ToList()'ing。
  • 每次创建新列表(queryCandidates.ToList().RemoveAt(i);) 时,从中删除一个项目并丢弃该列表
  • 空的catch{} 只会隐藏错误。最好删除它。

标签: c# list removeclass removeall


【解决方案1】:

ToList() 创建一个新实例。从这个实例中,您正在删除元素。您没有从原始枚举中删除元素。

你应该这样做:

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

请注意elementsToRemove 的使用。您不能直接在循环中删除项目。这将引发异常。


另外,请注意ToList 复制所有数据。每次你调用它。很明显,在循环中这样做不是一个好主意。

【讨论】:

  • 另一个问题是他/她试图在 foreach 循环中修改一个集合。这行不通。
  • @downvoter:请发表评论,以便我改进答案。
【解决方案2】:
queryCandidates.ToList().RemoveAt(i);

ToList() 创建一个全新的列表,然后您从中删除一个元素,但该列表早已不复存在。

试试:

var newList = queryCandidates.ToList();

for (int i=newList.Count-1; i>=0; i--){
 ///snip
 newList.RemoveAt(i);

请注意,我将您的 foreach 更改为 for(反向),因为您在使用 foreach 迭代列表时无法修改列表。

【讨论】:

    【解决方案3】:

    ToList() 函数在您每次调用它时都会创建一个新列表。该对象将从该列表中删除,而不是从原始列表中删除。所以你应该在 foreach 之前调用一次 ToList。

    一旦你完成了 removeAt() 调用将起作用并导致新的问题,因为你正在尝试从 foreach 循环中修改列表。因此,您需要以一种将 remove 也带出循环的方式重写您的代码。

    【讨论】:

      【解决方案4】:

      好吧,我不确定 queryCandidates 类型是什么,但您没有看到更新的原因是您从错误的对象中删除了元素“i”。您的 ToList() 函数创建一个 List 类型的新对象。如果您想保留更改,您需要缓存该列表并在使用原始 queryCandidates 对象的地方使用它。

      【讨论】:

      • 好的,谢谢你的快速回答,也让我注意到为什么它没有被保存结果
      • 没问题,但请注意,如果您尝试修改您正在迭代的列表,C# 可能会非常生气。因此,您可能必须将 foreach 循环更改为 while 循环(检查 i
      【解决方案5】:

      queryCandidates 不是列表。

      您正在将其转换为一个列表,该列表创建一个新实例,您从中删除该项目,但不影响 queryCandidates 本身。

      你可以这样做:

      var queryCandidates myCollection.ToList();

      然后

      queryCandidates.RemoveAt(i);

      【讨论】:

        【解决方案6】:

        对我有用的是从下往上删除:

        for (int i = list.Count - 1; i > 0; i--)
        {
            if (list[i][0] == "&nbsp;" || list[i][3] == "0")
                list.RemoveAt(i);
        }
        

        在减少项目数后遗漏一些项目是有道理的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-24
          • 1970-01-01
          • 2021-10-23
          • 2022-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-16
          相关资源
          最近更新 更多