Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用列表的缺点是什么<;T>;。RemoveAll喜欢ForEach吗?_C#_List_Foreach - Fatal编程技术网

C# 使用列表的缺点是什么<;T>;。RemoveAll喜欢ForEach吗?

C# 使用列表的缺点是什么<;T>;。RemoveAll喜欢ForEach吗?,c#,list,foreach,C#,List,Foreach,在一些代码中,我使用了List.RemoveAll作为一个特殊的列表。ForEach允许动态删除元素,因为我认为它会提供更好的性能:O(n)与RemoveAll中的一个组合循环相比O(2n)一个ForEach和一个RemoveAll 例如: gameObjects.RemoveAll( object => { if (object.Active){ // Doing stuffs on object } return !object.Active;

在一些代码中,我使用了
List.RemoveAll
作为一个特殊的
列表。ForEach
允许动态删除元素,因为我认为它会提供更好的性能:O(n)
RemoveAll
中的一个组合循环相比O(2n)一个
ForEach
和一个
RemoveAll

例如:

gameObjects.RemoveAll( object => {
    if (object.Active){
        // Doing stuffs on object
    }
    return !object.Active;
});
至少在我的代码中,这个黑客以正确的顺序进行迭代,迄今为止没有遇到任何bug

这种方法的一个缺点是代码的可维护性/可读性,因为它不是这种方法最初的目的,可能会在以后引起混淆


所以我的问题是:这种方法还有其他缺点吗(性能、可能的bug等等)?

在一次迭代中做两倍的工作实际上并不是两次迭代的效率的两倍,每次迭代做一半的工作

在一英里长的赛道上跑一圈,还是在半英里长的赛道上跑两圈,哪个更快


您试图在一次迭代中完成所有这些工作,这会使代码变得不必要的复杂,而实际上您并没有从中受益。只需调用一次
RemoveAll
即可删除所有非活动项,然后调用集合上的
foreach
对活动项执行操作。

我在Stackoverflow上发现: 我想你的方法行得通,我看没问题,但正如你所说的,也许有一天会很难理解。我更喜欢“回环”

这是上面链接中描述的另一种方式:正如智者所评论的,这是O(n*m)-最坏的情况吗

var list = new List<int>(Enumerable.Range(1, 10));
for (int i = list.Count - 1; i >= 0; i--)
{
    if (list[i] > 5)
    list.RemoveAt(i);
 }
list.ForEach(i => Console.WriteLine(i));
var list=新列表(可枚举范围(1,10));
对于(int i=list.Count-1;i>=0;i--)
{
如果(列表[i]>5)
列表。删除(i);
}
list.ForEach(i=>Console.WriteLine(i));

我不相信这是一种黑客行为,而是以特定方式使用设计元素。因为它似乎正在按照文档执行其工作,因此会删除与指定谓词定义的条件匹配的所有元素。()

…以正确的顺序进行迭代,但没有遇到 到目前为止

这里有两个步骤,一个是对每个项目进行操作,第二个是从列表中删除。使用此方法有效且可读。已预先确定删除的事实无关紧要

纯粹主义者会抱怨,但无论如何操作都需要遍历项目,为什么不集中作业呢

代码可维护性/可读性

对于维护…只需向任何未来的开发人员评论意图

这种黑客还有其他缺点吗(性能、可能的bug等等)


不,我认为hack有两个循环,而逻辑上可以完成一个循环。

这里需要更好的性能吗?你有没有看到你的代码中有一个性能问题可以证明“hack”是正确的?你写O(2n)是什么意思?这不是你所说的“hack”?如果你依赖于维持秩序,就不要用这个。没有这样的保证。除此之外,这是一个风格的问题——有人可能不在乎,有人可能想把你的四肢和身体分开。忘了算法的复杂性吧——你也不能保证这一点,因为
RemoveAll
方法(或
ForEach
方法)的实现不是合同的一部分。在任何情况下,在所有更新之后推迟删除可能会更好,否则当对象依赖于其他对象,并且您以未指定的顺序删除它们时,您会得到很多乐趣。@Tr1et但是O(2n)==O(n)。通过调用
RemoveAt
m
次从列表中删除
m
项是O(n*m),调用
RemoveAll
是O(n),因为它只需要对列表进行一次碎片整理。您建议让OP的代码变得更糟糕,无论是在可读性方面,还是在性能方面,都是如此,并且在您因提供有害内容而遭到否决时抱怨?你认为我应该投票给一个建议有害改变的帖子,尽管我知道的更好?我没那么刻薄。其他人发布了一个错误的问题解决方案并不意味着它不是一个错误的问题解决方案(尽管也要注意,该答案确实提到了
RemoveAll
)。最后,虽然只显式迭代一次,但
RemoveAt
必须在内部迭代该集合。。。。你真的会在没有机会的情况下否决任何东西。问题是,是否有另一种更具可读性的方式——如果是这样,这就是答案,als 400+的人在上面的帖子中思考。我甚至在上面说过,这是同一个问题——或多或少是重复的……嘿,伙计们。这段对话毫无意义。让我们继续。您似乎假设正在做的工作是计算是否要删除该项。不是。业务逻辑是删除所有非活动项,并对所有活动项执行一些工作。它们在概念上是独立的操作;OP询问为了提高性能,将这些单独的业务任务组合成一个方法调用的优点。如果正在执行的操作是确定是否应该删除该项,那么这将是一个完全不同的问题。您觉得此转换非常混乱,以至于您觉得它需要一个注释,以便向未来的读者解释它的操作,这一事实非常强烈地表明它并没有更多可读/可维护,而不是分离单独的操作。如果您觉得将它们组合在一起更具可读性,那么为什么值得这样解释呢?除非迭代成本很高(例如,创建枚举器时会出现长时间运行的情况),否则像这样的技巧就可以了。
List.RemoveAll()
不是这种情况。谢谢,所以可以放一些琐碎的东西,比如