2011-06-23 43 views
7
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>,那麼這很重要嗎?Count()(linq擴展名)和List <T>。Count

回答

10

讓我們來看看有反射:

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財產。

0

我認爲它的工作原理是這樣的:List將自己的計數保存在一個變量中。 Count()通過IEnumerable循環來計算元素的數量。這將使List.Count更有效率。

+0

如果IEnumerable是ICollection(如List),因此具有.Count屬性,那麼當您使用.Count()方法時,Linq會將其用作快捷方式。這意味着無論你使用什麼都不重要。 – Dolbz

+0

這是錯誤的。 Count()被編碼爲它只循環計算,如果你調用Count()的元素沒有實現ICollection本身。 –

3

如果Linq Count方法實現ICollection接口並且已具有Count屬性,則該方法足夠聰明,不會遍歷基礎集合。

1

IEnumerable上的計數實現首先檢查可枚舉列表是否也實現ICollection<T>其中T是可枚舉列表的泛型參數。如果是,則返回ICollection<T>.Count

如果不是,它會檢查它是否執行ICollection。如果是,則返回ICollection.Count

如果它沒有實現那些它必須遍歷整個列表並計數,這可能是一個大列表的昂貴操作。

List<string>然而執行ICollection<string>,因此性能將是相同的。