用于列表的Count方法或属性

本文关键字:属性 方法 Count 列表 用于 | 更新日期: 2023-09-27 18:19:22

感谢您向我解释IList和IEnumerable。我把那个问题标为已回答。现在我需要更多的信息。

我有这样的代码:

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) 

用于列表的Count方法或属性

Count()扩展方法适用于支持IEnumerable的所有对象,并且由于IEnumerable本身没有任何报告项目计数的方法,因此可能具有来迭代使用IEnumeratorIEnumerable实例,这可能是一个真正的性能打击,如果多次调用。

然而,如果您查看Count()的实现,您将看到它针对ICollection类型进行了优化(包括泛型和非泛型,至少在FW4.0中,这意味着IListIList<T>也进行了优化),并且如果您的对象实现了ICollection(在Count属性中报告项目计数),Count()方法返回项目计数而无需通过集合迭代。这就是你看不到性能差异的原因。然而,如果您知道您有ICollectionIList实例,为什么不直接获得Count属性并独立于Count()方法实现呢?

另外,请记住,您可以在变量中缓存Count()方法的返回值,以抑制多次调用:

var count = Model.Items.Count();
for(var index = 0; index < count; index++) { }

Count()方法调用实际上调用静态Enumerable.Count()方法。这针对IList实现进行了优化,以便使用该属性——但这需要进行动态类型检查,并且最终仍将传递到该属性——因此使用该属性肯定更有效。在。net 3.5中,它只针对ICollection<T>进行了优化,而在。net 4中,它也针对非泛型ICollection进行了优化。更多细节,请参阅我在Count上的Edulinq博客文章。

至于你问题的最后一点:foreach循环可能会或可能不会更有效,但在我看来,它会更可读,这是相当重要的。我肯定会使用foreach,除非你真的需要每个条目的索引