C# RemoveAt()和Remove()工作差异

C# RemoveAt()和Remove()工作差异,c#,list,C#,List,我刚刚注意到一件非常尴尬的事情,我测试了RemoveAt()和Remove()两种方法,但它们的工作原理不同,我想知道是否有人能解释原因。基本上,在本例中,成功从列表中删除特定项的唯一方法是Remove() List testList=新列表{1,76,3,4,5,76,76,8}; 公共无效删除元素() { for(int i=0;i=0;i--) { //RemoveAt期权 if(testList[i]==76)testList.RemoveAt(i); } } 以下是您的列表中包含的内容

我刚刚注意到一件非常尴尬的事情,我测试了RemoveAt()和Remove()两种方法,但它们的工作原理不同,我想知道是否有人能解释原因。基本上,在本例中,成功从列表中删除特定项的唯一方法是Remove()

List testList=新列表{1,76,3,4,5,76,76,8};
公共无效删除元素()
{
for(int i=0;i
A的输出为:1,3,4,5,8 B的输出为:1,3,4,5,76,8 C的输出为:1,3,4,5,76,8


谢谢你抽出时间

Remove
从集合中删除与指定元素相等的元素
RemoveAt
删除指定位置的元素。

按索引删除项目会更改其后面项目的索引。这可能会导致跳过某些项目。如果要在遍历列表时使用RemoveAt,请尝试反向迭代。

代码中的
Remove
RemoveAt
函数实际上工作正常。但是,如果您在列表中循环,使用
RemoveAt
是提高效率的更好的功能,因为
Remove
必须再次搜索列表,以找到出现
76
的第一种情况,而
RemoveAt
已经知道在该位置删除项目的确切索引

问题的出现是因为您在列表中循环的方式

当您迭代并从列表中删除项目时,列表向左移动一个索引,以填充刚刚删除的项目,而
i
索引仍在同一位置(跳过下一个项目)。
通常,如果要从列表中删除元素,最好的做法是向后遍历列表,因为结束点取决于它是否达到0,并处理列表每次向左移动,而不会跳过下一个元素

List<int> testList = new List<int>{1,76,3,4,5,76,76,8};

public void RemoveElements()
{
    for (int i = testList.Count - 1; i >= 0; i--)
    {
        // RemoveAt option
        if(testList[i] == 76) testList.RemoveAt(i);
    }
}
List testList=新列表{1,76,3,4,5,76,76,8};
公共无效删除元素()
{
对于(int i=testList.Count-1;i>=0;i--)
{
//RemoveAt期权
if(testList[i]==76)testList.RemoveAt(i);
}
}

以下是您的列表中包含的内容:

i:             0   1   2   3   4   5   6   7
testList[i]:   1  76   3   4   5  76  76   8

现在考虑在循环迭代时发生什么,<代码> i=5 ,这意味着<代码> TestList[i] < /C>是您的两个相邻的76ES中的第一个。在版本B或C中运行代码将从

testList
中删除元素5,导致其后面的元素向下移动一个索引。所以
testList[6]
,原来是76,现在是8;而
testList[7]
,原来是8,现在已经超过了列表的末尾。下一次循环运行时,它将与<代码> i==6 ,这意味着代码将考虑值8,而不是您的76ES中的第二个。第二个76已被完全跳过

这就是hatchet对你的问题的评论背后的原因,他说如果你必须遍历列表,你应该反过来做。如果是向后迭代,那么删除元素会将元素的位置进一步向下移动并不重要,因为您已经处理了这些元素。当然,更好的方法仍然是使用一种根本不需要迭代的解决方案,例如。

“输出”?你什么也不打印,什么也不返回。当你在列表上迭代时,从列表中删除会导致麻烦。但如果您坚持这样做,至少要从头到尾迭代,这样删除操作就不会导致跳过元素。
i:             0   1   2   3   4   5   6   7
testList[i]:   1  76   3   4   5  76  76   8