计算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
/ finally
和using
语句。
为了在其他情况下简化这个过程,你可以在编译时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可以用来指示以下哪种技术是最好的标准方法:
- 直接询问对象。 支持IEnumerable的某些types的对象(如Array,List和Collection)具有可直接报告其中元素数量的属性。
- 枚举所有项目,放弃它们,并计数枚举项目的数量。
- 枚举所有项目到一个列表,然后使用列表,如果有必要再次使用枚举。
以上各项在不同的情况下都是最佳的。
我认为select代表你的元素序列的types应该是ICollection,而不是IEnumerable 。
ICollection
和ICollection<T>
提供Count属性,另外每个ICollection都实现IEnumearable。