C# 为什么可能的多重枚举不好?

Roy*_*ris 5 c# enumeration

Visual Studio 在IEnumerable. 然后我添加ToList()它。但我开始想知道为什么这是一个不好的做法。

那么为什么多次枚举不好呢?

Ran*_*ner 5

\xe2\x80\x9c IEnumerable\xe2\x80\x9c 的可能多重枚举是重新锐化器警告。如果您多次枚举一个可枚举项,ReSharper 将检测到这一点并向您发出警告。尽管这个警告乍一看似乎毫无意义,但有两个充分的理由值得关注:

\n
    \n
  1. 枚举一个可枚举项可能会非常昂贵。例如,可枚举可能由数据库支持。重新枚举可能会迫使您等待另一次网络往返。您不想支付两次费用。

    \n
  2. \n
  3. 由多个枚举引起的性能问题会自行加剧。

    \n
  4. \n
\n

请查看这篇文章以获取有关此警告的更多信息:http://twistedoakstudios.com/blog/Post7694_achieving-exponential-slowdown-by-enumeating-twice

\n

  • 还有第三个也是更重要的原因;枚举*不保证可重复* - 它可能返回完全不同的数据,或者根本无法重复;例如,考虑一个通过开放的“Socket”从外部数据中提取数据的可枚举(其中它不控制另一端),或者数据来自某种 RNG(特别是 CRNG 或 PRNG)其中种子不是枚举器源的一部分) (4认同)

Erm*_*ary 2

您实际上在代码中循环了两次集合,这就是您收到 ReSharper 警告的原因。

例如,当使用IEnumerable数据库调用返回的数据时,这意味着获取数据两次,从而减慢应用程序的速度并导致不必要的数据库负载。为什么要获取两次数据?

如果在内存中使用可枚举值,则根据集合的大小,对集合进行多次枚举也可能会非常昂贵。

使用可以解决该错误,因为它通过将 转换为列表来.ToList()强制在变量初始化时进行枚举(您也可以通过使用 将 强制转换为数组来强制执行此操作)。IEnumerableIEnumerableToArray

集合内的数据IEnumerable也可能在枚举之间发生变化,因此最好在需要数据保持不变的位置强制枚举(每次循环时,可枚举中的项目可能会有所不同)。

由 JetBrains 自己编写:代码检查:IEnumerable 的可能多重枚举