IEnumerable vs T

我只是意识到,在将T[]暴露给我的视图时,我可能总是错了,而不是IEnumerable

通常,对于这种代码:

 foreach (var item in items) {} 

item应该是T[]还是IEnumerable

如果我需要得到项目的计数,那么Array.Count会比IEnumerable.Count()更快吗?

出于其他原因列出的原因, IEnumerable通常是更好的选择。 但是,我想提出一个关于Count()观点。 当他说类型本身实现Count()时,Quintin是不正确的。 它实际上是在Enumerable.Count()中实现的扩展方法,这意味着其他类型不会覆盖它以提供更有效的实现。

默认情况下, Count()必须遍历整个序列以计算项目。 但是,它确实知道ICollectionICollection ,并针对这些情况进行了优化。 (在.NET 3.5 IIRC中,它仅针对ICollection进行了优化。)现在数组确实实现了这一点,因此Enumerable.Count() ICollection.Count并避免迭代整个序列。 它仍然比直接调用Length稍慢,因为Count()必须发现它实现ICollection以开始 – 但至少它仍然是O(1)。

对于一般性能来说,同样的事情也是如此:当迭代数组而不是一般序列时,JITted代码可能会更紧凑。 您基本上可以为JIT提供更多信息,甚至C#编译器本身也会以不同的方式处理数组(直接使用索引器)。

但是,对于大多数应用程序而言,这些性能差异将无关紧要 – 在我有充分理由不这样做之前,我肯定会使用更通用的接口。

这部分无关紧要,但标准理论将规定“针对接口的程序,而不是实现”。 使用接口模型,只要符合相同的接口,就可以更改传递的实际数据类型,而不会影响调用者。

与此形成对比的是,您可能有理由专门公开数组,在这种情况下需要表达。

对于你的例子,我认为IEnumerable是可取的。 还值得注意的是,出于测试目的,使用界面可以减少您在特定课程中所产生的头痛量,您将不得不一直重新创建,集合通常不是那么糟糕,但有接口合同你可以轻松嘲笑是非常好的。

添加进行编辑:
这是无关紧要的,因为底层数据类型将实现Count()方法,对于应该访问已知长度的数组,我不担心该方法的任何感知开销。 有关 Count()实现的解释, 请参阅Jon Skeet的答案 。

T [](一个大小,基于零)也使用IEnumerable实现ICollectionIList IEnumerable

因此,如果您希望在应用程序中使用较少的耦合,则IEnumerable更可取。 除非你想在foreach内部进行索引访问。

由于Array类实现了System.Collections.Generic.IListSystem.Collections.Generic.ICollectionSystem.Collections.Generic.IEnumerablegenerics接口,我会使用IEnumerable,除非你需要使用这些接口。

http://msdn.microsoft.com/en-us/library/system.array.aspx

你的直觉是正确的,如果所有的观点关心或者应该关心的是,有一个可枚举的,那就是它在界面中应该要求的全部。

从外部逻辑上(概念上)是什么?

如果是数组,则返回数组。 如果唯一的一点是枚举,则返回IEnumerable。 否则IList或ICollection可能是要走的路。

如果您想提供许多function但不允许对其进行修改,那么可以在内部使用List并返回从它的.AsReadOnly()方法返回的ReadonlyList。

鉴于稍后将代码从数组更改为IEnumerable很容易,但是换另一种方式不是,我会使用IEnumerable,直到你知道你需要返回数组的小spead benfit。