2015-09-30 2 views
3

Рассмотрим следующий код:Вызывает ли счетчик на IEnumerable итерирование всей коллекции?

static IEnumerable<int> GetItems() 
{ 
    return Enumerable.Range(1, 10000000).ToArray(); // or: .ToList(); 
} 

static void Main() 
{ 
    int count = GetItems().Count(); 
} 

Будет ли итерацию по всем 10 миллиардов чисел и считать их один за одним, или он будет использовать массив в Length/Листом Count свойства?

+2

Нет, 'Length' (в случае массива) или' Count' (в случае 'IList ') будет использоваться –

+3

См. Http://stackoverflow.com/questions/2521592/difference-between-ienumerable- count-and-length –

+2

Вы можете найти реализацию самостоятельно :) http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,41ef9e39e54d0d0b –

ответ

4

Если IEnumerable является ICollection, он вернет собственность Count.

Вот source code:

public static int Count<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null) throw Error.ArgumentNull("source"); 
    ICollection<TSource> collectionoft = source as ICollection<TSource>; 
    if (collectionoft != null) return collectionoft.Count; 
    ICollection collection = source as ICollection; 
    if (collection != null) return collection.Count; 
    int count = 0; 
    using (IEnumerator<TSource> e = source.GetEnumerator()) 
    { 
     checked 
     { 
      while (e.MoveNext()) count++; 
     } 
    } 
    return count; 
} 

Массив реализует ICollection<T>, так что не нужно быть перечислены.

+0

Итак, соответствует ли приведенный код 'ICollection' или нет? –

+0

@PatrickHofman * Какой * код? –

+0

'return Enumerable.Range (1, 10000000) .ToArray(); // или: .ToList(); ', как в вопросе. –

0

Код сначала поместит все целые числа в массив (из-за вашего вызова .ToArray()), а затем вернет длину массива (начиная с all arrays implement ICollection), который вызывает фактический код. Он не будет считать все элементы массива поодиночке.

+0

Я не могу обнаружить массив в исходном коде, представленный @Jakub, и я не вижу причины, почему его следует создать. –

+2

@PeterSchneider В коде от OP есть только код: 'return Enumerable.Range (1, 10000000) .ToArray(); 'Код явно называет' ToArray'. –

+0

Ох. Я неправильно понял. Что ж. Я думаю, что ответ OP - «вы просто сделали что-то безумное, но компилятор не добавит безумия сверху». Я предполагаю, что компиляторам C# разрешено применять правило as-if, поэтому компилятору разрешено вообще ничего не делать (поскольку программа не имеет наблюдаемого эффекта). Если вы печатаете счет, компилятор может свободно печатать 10000000, без массивов или чего-то еще. –

Смежные вопросы