IEnumerable与列表的FOR-EACH

时间:2019-02-12 18:38:34

标签: c#

如果我将for-each循环作为方法参数传递给我,而我将IEnumerable作为参数传递给我,或者如果我将这个参数作为List传递给我,则有什么好处或不同?

5 个答案:

答案 0 :(得分:7)

如果您的IEnumerable由List实现,则为否;没有不同。但是,在概念上有很大的不同。 IEnumerable会说“我可以枚举”,这也意味着项目的数量未知,枚举不能反向,也不能随机访问。列表说:“我是一个完整的列表,已经填充;可以反转并可以随机访问”。

因此,通常应该构建功能接口以接受与您的操作兼容的最低功能;如果只打算迭代地枚举枚举,则接受IEnumerable-这可以在更多情况下使用您的函数。

如果您让函数仅接受List(),那么任何传入了数组或IEnumerable的调用方都必须在调用函数之前将其输入转换为List()-与直接通过其数组进行传递相比,这可能会降低性能或IEnumerable直接。从这个意义上说,接受IEnumerable会带来更好的性能代码。

答案 1 :(得分:5)

在一般情况下,如果集合具有显式接口实现IEnumerable

,则 会有所不同

列表具有显式实现,但不会更改行为。您的情况没有区别。 请参阅:https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs查看GetEnumerator及类似内容

答案 2 :(得分:3)

不,没有。在这两种情况下,for-each都被翻译成这样

var enumerator = input.GetEnumerator();
while(enumerator.MoveNext())
{
    // loop body.
    // The current value is accessed through: enumerator.Current
}

另外,如果枚举器是一次性的,它将在循环之后丢弃。

Jon Skeet给出了详细的说明here

答案 3 :(得分:0)

如果传递相同的对象,则方法接受IEnumerable还是List都没有关系。

但是,如果在方法内部要做的只是枚举对象,则最好在method参数中期望IEnumerable,而不必通过期望List来限制方法的调用者。 / p>

答案 4 :(得分:0)

不,关于foreach循环遍历集合的方式没有好处也没有区别。 正如 Olivier Jacot-Descombes 所指出的那样,foreach循环将使用枚举器简单地逐个遍历元素。

但是,如果您的逻辑至少两次遍历同一集合 ,则可能会有所不同。在这种情况下,如果使用IEnumerable<>,则每次遍历迭代器时,都可能最终重新生成元素。 ReSharper甚至针对此类型的代码发出特殊警告:PossibleMultipleEnumeration 我并不是说您不应该使用IEnumerable<>。一切都有其时间和地点,使用最通用的接口并不总是一个好主意。选择时要小心。