sta*_*ker 21 c# arrays collections ienumerable
我只是意识到,也许我在揭露T[]
我的观点时总是错了,而不是IEnumerable<T>
.
通常,对于这种代码:
foreach (var item in items) {}
Run Code Online (Sandbox Code Playgroud)
item
应该T[]
还是IEnumerable<T>
?
而且,如果我需要得到物品的数量,那么Array.Count
会更快IEnumerable<T>.Count()
吗?
Jon*_*eet 31
IEnumerable<T>
由于其他地方列出的原因,这里通常是更好的选择.但是,我想提出一点意见Count()
.当他说类型本身实现时,Quintin是不正确的Count()
.它实际上是Enumerable.Count()
作为扩展方法实现的,这意味着其他类型不会覆盖它以提供更有效的实现.
默认情况下,Count()
必须迭代整个序列以计算项目.但是,它确实知道ICollection<T>
并且ICollection
针对这些情况进行了优化.(在.NET 3.5 IIRC中,它仅针对优化ICollection<T>
.)现在数组确实实现了这一点,因此Enumerable.Count()
遵循ICollection<T>.Count
并避免迭代整个序列.它仍然比Length
直接调用稍慢,因为Count()
必须发现它实现ICollection<T>
开始 - 但至少它仍然是O(1).
对于性能而言,同样的事情也是如此:当迭代数组而不是一般序列时,JITted代码可能会更紧凑.您基本上可以为JIT提供更多信息,甚至C#编译器本身也会以不同的方式处理数组(直接使用索引器).
但是,对于大多数应用程序而言,这些性能差异将无关紧要- 在我有充分理由不这样做之前,我肯定会使用更通用的接口.
这部分无关紧要,但标准理论将规定"针对接口的程序,而不是实现".使用接口模型,只要符合相同的接口,就可以更改传递的实际数据类型,而不会影响调用者.
与此形成鲜明对比的是,您可能有理由专门公开数组,并且在这种情况下需要表达它.
对于你的例子,我认为IEnumerable<T>
是可取的.还值得注意的是,出于测试目的,使用界面可以减少您在特定课程中所产生的头痛量,您不得不一直重新创建,集合通常不是那么糟糕,但是有一个接口契约你可以轻松嘲笑是非常好的.
添加用于编辑:
这更无关紧要,因为底层数据类型将实现该
有关Count()
方法,对于应该访问已知长度的数组,我不担心该方法的任何感知开销.Count()
实施的解释,请参阅Jon Skeet的答案.
归档时间: |
|
查看次数: |
4357 次 |
最近记录: |