感谢您向我解释有关IList和IEnumerable的帮助。我已将question标记为已回答。现在我要求提供更多信息。
我有这样的代码:
for (var index = 0; index < Model.Items.Count(); index++)
在之前的帖子中建议它效率不高,因为Count()是一个方法,它会多次执行。我尝试了以下方法:
for (var index = 0; index < Model.Items.Count; index++)
这似乎有效。
有人可以确认是否存在差异。两者都有效,所以我不是百分百肯定。
以下是最有效的吗? foreach是否需要IList或IEnumerable?
foreach(var item in Items)
答案 0 :(得分:6)
Count()
扩展方法适用于支持IEnumerable
的所有对象,由于IEnumerable
本身没有任何报告项目计数的方法,因此可能使用它IEnumerable
迭代IEnumerator
实例,如果多次调用,这可能是真正的性能损失。
但是,如果你研究Count()
实现,你会看到它针对ICollection
类型进行了优化(通用和非通用,至少在FW4.0中,意味着{{1}并且IList
也已优化),如果您的对象实现IList<T>
(报告ICollection
属性中的项目计数),Count
方法返回项目计数而不迭代集合。这就是为什么你没有看到性能差异的原因。不过,如果您知道自己有Count()
或ICollection
个实例,为什么不直接获取IList
属性并独立于Count
方法实现?
另外,请记住,您可以在变量中缓存Count()
方法的返回值以抑制多个调用:
Count()
答案 1 :(得分:4)
Count()
方法调用实际上调用静态Enumerable.Count()
方法。这针对IList
实现进行了优化以使用该属性 - 但这需要动态类型检查,并且最终仍然会进入属性 - 因此使用该属性肯定更有效。在.NET 3.5中,它仅针对ICollection<T>
进行优化,而在.NET 4中,它也针对非泛型ICollection
进行了优化。有关详细信息,请参阅my Edulinq blog post on Count
。
至于你问题的最后一点:foreach
循环可能会或可能不会更有效,但在我的视图中它会更加可读,这一点更为重要。我肯定会使用foreach
,除非你真的需要每个条目的索引。