计算IEnumerable的计数(非通用)

任何人都可以帮助我IEnumerable Count扩展方法(非通用接口)。

我知道这不是在LINQ支持,但如何手动写入?

最简单的forms是:

 public static int Count(this IEnumerable source) { int c = 0; using (var e = source.GetEnumerator()) { while (e.MoveNext()) c++; } return c; } 

然后,您可以通过查询ICollection来改进:

 public static int Count(this IEnumerable source) { var col = source as ICollection; if (col != null) return col.Count; int c = 0; using (var e = source.GetEnumerator()) { while (e.MoveNext()) c++; } return c; } 

更新

正如Gerard在注释中指出的那样,非genericsIEnumerable不会inheritanceIDisposable所以正常的using语句将不起作用。 如果可能,尝试处理这种枚举数可能仍然很重要 – 迭代器方法实现IEnumerable ,因此可以间接传递给此Count方法。 在内部,该迭代器方法将取决于对Dispose的调用以触发其自己的try / finallyusing语句。

为了在其他情况下简化这个过程,你可以在编译时using你自己的using语句版本:

 public static void DynamicUsing(object resource, Action action) { try { action(); } finally { IDisposable d = resource as IDisposable; if (d != null) d.Dispose(); } } 

然后更新的Count方法将是:

 public static int Count(this IEnumerable source) { var col = source as ICollection; if (col != null) return col.Count; int c = 0; var e = source.GetEnumerator(); DynamicUsing(e, () => { while (e.MoveNext()) c++; }); return c; } 
 yourEnumerable.Cast<object>().Count() 

关于表演的评论:

我认为这是过早优化的一个很好的例子,但是在这里你会发现:

 static class EnumerableExtensions { public static int Count(this IEnumerable source) { int res = 0; foreach (var item in source) res++; return res; } } 

不同types的IEnumerable具有不同的确定计数的最佳方法; 不幸的是,没有通用的方法来知道哪种方法对于任何给定的IEnumerable来说都是最好的,甚至没有任何一种IEmumerable可以用来指示以下哪种技术是最好的标准方法:

  1. 直接询问对象。 支持IEnumerable的某些types的对象(如Array,List和Collection)具有可直接报告其中元素数量的属性。
  2. 枚举所有项目,放弃它们,并计数枚举项目的数量。
  3. 枚举所有项目到一个列表,然后使用列表,如果有必要再次使用枚举。

以上各项在不同的情况下都是最佳的。

我认为select代表你的元素序列的types应该是ICollection,而不是IEnumerable

ICollectionICollection<T>提供Count属性,另外每个ICollection都实现IEnumearable。