如果我将for-each
循环作为方法参数传递给我,而我将IEnumerable
作为参数传递给我,或者如果我将这个参数作为List
传递给我,则有什么好处或不同?
答案 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<>
。一切都有其时间和地点,使用最通用的接口并不总是一个好主意。选择时要小心。