Is there a difference between Count() (linq extension) and List<T>.Count
List<string> list = new List<string>() {"a", "b", "c"};
IEnumerable<string>开发者_如何学Go enumerable = list;
int c1 = list.Count;
int c2 = list.Count();
int c3 = enumerable.Count();
Are there differences in performance and implementation between these last 3 statements? Will list.Count()
perform worse or the same as list.Count
, and does it matter if the reference is of type IEnumerable<string>
?
Let's look with 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;
}
So, if your IEnumerable<T>
implements ICollection<T>
or ICollection
, it will return the Count
property.
The Linq Count method is clever enough not to iterate over the underlying collection if it implements ICollection interface and therefore already has Count property.
The implementation of the count on IEnumerable
first checks if the enumerable list also implements ICollection<T>
where T is the generic parameter of the enumerable list.
If it does, it returns ICollection<T>.Count
.
If not, it checks if it implements ICollection
. If it does it returns ICollection.Count
.
If it does not implement neither of those it has to iterate through the entire list and count, and this might be a expensive operation for a big list.
List<string>
however implements ICollection<string>
and therefore the performance will be the same.
I assume it works like this: a List keeps its own count in a variable. Count() loops through the IEnumerable to count the number of elements. That would make List.Count more efficient.
精彩评论