计算IEnumerable的计数(非通用)

Hom*_*mam 46 .net c# linq ienumerable extension-methods

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

我知道LINQ不支持它但是如何手动编写它?

Las*_*olt 47

yourEnumerable.Cast<object>().Count()
Run Code Online (Sandbox Code Playgroud)

关于绩效的评论:

我认为这是过早优化的一个很好的例子,但是你走了:

static class EnumerableExtensions
{
    public static int Count(this IEnumerable source)
    {
        int res = 0;

        foreach (var item in source)
            res++;

        return res;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ Daniel的回答检查`ICollection`更好,值得... (4认同)

Dan*_*ker 42

最简单的形式是:

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

然后,您可以通过查询来改进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;
}
Run Code Online (Sandbox Code Playgroud)

更新

正如Gerard在评论中指出的那样,非泛型IEnumerable不会继承,IDisposable因此正常的using陈述不起作用.如果可能的话,尝试处理这样的枚举器可能仍然很重要 - 迭代器方法实现IEnumerable,因此可以间接传递给此Count方法.在内部,迭代器方法将依赖于调用Dispose来触发它自己的try/ finallyusing语句.

为了在其他情况下也很容易,你可以using在编译时制作自己的语句版本,这个版本不那么繁琐:

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

然后更新的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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了这个扩展,`using` 给出了`System.Collections.IEnumerable` 的编译错误。我将代码更改为编译的`Count&lt;T&gt;(this IEnumerable&lt;T&gt; source)`。 (2认同)