IEnumerable
不支持这个.这是设计的.IEnumerable
在您需要之前使用延迟评估来获取您要求的元素.
如果你想知道项目的数量,而不是迭代它们你可以使用ICollection
,它有一个Count
属性.
IEnumerable
不支持这个.这是设计的.IEnumerable
在您需要之前使用延迟评估来获取您要求的元素.
如果你想知道项目的数量,而不是迭代它们你可以使用ICollection
,它有一个Count
属性.
在System.Linq.Enumerable.Count
对扩展方法IEnumerable
有以下实现:
ICollectionc = source as ICollection ; if (c != null) return c.Count; int result = 0; using (IEnumerator enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) result++; } return result;
所以它试图转换为ICollection
具有Count
属性的属性,并在可能的情况下使用它.否则它会迭代.
因此,最好的Count()
办法是在IEnumerable
对象上使用扩展方法,因为这样可以获得最佳性能.
只需添加额外的一些信息:
该Count()
扩展并不总是迭代.考虑Linq to Sql,其中计数进入数据库,但不是返回所有行,而是发出Sql Count()
命令并返回该结果.
此外,编译器(或运行时)足够智能,Count()
如果有一个对象方法,它将调用它.所以它并不像其他响应者所说的那样,完全无知并且总是为了计算元素而迭代.
在许多情况下,程序员只是if( enumerable.Count != 0 )
使用Any()
扩展方法进行检查,因为if( enumerable.Any() )
linq的惰性评估效率更高,因为一旦确定有任何元素,它就会短路.它也更具可读性
我的一位朋友有一系列博客文章,说明了为什么你不能这样做.他创建了返回IEnumerable的函数,其中每次迭代返回下一个素数,一直到ulong.MaxValue
,并且在您要求之前不会计算下一个项目.快速流行问题:返回了多少项?
这是帖子,但它们有点长:
Beyond循环(提供其他帖子中使用的初始EnumerableUtility类)
迭代的应用(初始实现)
疯狂扩展方法:ToLazyList(性能优化)
没有迭代,IEnumerable不能计数.
在"正常"情况下,实现IEnumerable或IEnumerable
相反,Count它是一个扩展方法,在静态类Enumerable上定义.这意味着它可以在IEnumerable
或者,您可以执行以下操作:
Tables.ToList().Count;
不,不是一般的.使用枚举的一点是,枚举中的实际对象集是未知的(事先,甚至根本不知道).
您可以使用System.Linq.
using System; using System.Collections.Generic; using System.Linq; public class Test { private IEnumerableTables { get { yield return "Foo"; yield return "Bar"; } } static void Main() { var x = new Test(); Console.WriteLine(x.Tables.Count()); } }
你会得到结果'2'.
超越您的直接问题(已经完全回答了否定),如果您希望在处理可枚举时报告进度,您可能需要查看我的博客帖子报告Linq查询期间的进度.
它可以让你这样做:
BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += (sender, e) => { // pretend we have a collection of // items to process var items = 1.To(1000); items .WithProgressReporting(progress => worker.ReportProgress(progress)) .ForEach(item => Thread.Sleep(10)); // simulate some real work };