Count()(linq扩展名)和List <t> .Count </t>之间有区别吗?

时间:2011-06-23 07:50:34

标签: c# list

List<string> list = new List<string>() {"a", "b", "c"};
IEnumerable<string> enumerable = list;

int c1 = list.Count;
int c2 = list.Count();
int c3 = enumerable.Count();

最后3个陈述之间在性能和实施方面是否存在差异? list.Count()的效果会与list.Count的表现更差或相同吗,如果引用的类型为IEnumerable<string>,那么它是否重要?

4 个答案:

答案 0 :(得分:10)

让我们看一下Reflector:

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<TSource> is2 = source as ICollection<TSource>;
    if (is2 != null)
    {
        return is2.Count;
    }
    ICollection is3 = source as ICollection;
    if (is3 != null)
    {
        return is3.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}

因此,如果您的IEnumerable<T>实施ICollection<T>ICollection,则会返回Count属性。

答案 1 :(得分:3)

Linq Count方法非常聪明,如果它实现ICollection接口并且因此已经具有Count属性,则不会迭代底层集合。

答案 2 :(得分:1)

IEnumerable上的计数实现首先检查可枚举列表是否也实现ICollection<T>,其中T是可枚举列表的泛型参数。

如果是,则返回ICollection<T>.Count

如果没有,它会检查它是否实现ICollection。如果是,则返回ICollection.Count

如果它没有实现那些它必须迭代整个列表并计数,这对于大列表来说可能是一个昂贵的操作。

然而,

List<string>实现ICollection<string>,因此性能将相同。

答案 3 :(得分:0)

我认为它的工作方式如下:List在变量中保留自己的计数。 Count()遍历IEnumerable以计算元素的数量。这将使List.Count更有效率。