任何人都可以帮助我使用Count
IEnumerable
扩展方法(非通用接口)。
我知道LINQ不支持它但是如何手动编写它?
答案 0 :(得分:47)
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;
}
}
答案 1 :(得分:42)
最简单的形式是:
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在评论中指出的那样,非通用IEnumerable
不会继承IDisposable
,因此正常的using
语句将无效。如果可能的话,尝试处理这样的枚举器可能仍然很重要 - 迭代器方法实现IEnumerable
,因此可以间接传递给此Count
方法。在内部,该迭代器方法将取决于对Dispose
的调用,以触发其自己的try
/ finally
和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;
}
答案 2 :(得分:4)
不同类型的IEnumerable有不同的最佳方法来确定计数;遗憾的是,没有通用的方法可以知道哪种方法最适合任何给定的IEnumerable,甚至没有任何标准方法可以通过IEmumerable来指示以下哪种技术最佳:
以上各项在不同情况下都是最佳的。
答案 3 :(得分:3)
我认为选择用于表示元素序列的类型应该首先是 ICollection而不是IEnumerable 。
ICollection
和ICollection<T>
都提供了Count属性 - 而且 - 每个ICollection也实现了IEnumearable。