Я думаю, что использование Slice()
будет немного вводить в заблуждение. Я думаю об этом как о средстве, позволяющем мне вставить массив в новый массив и не вызывать побочных эффектов. В этом сценарии вы бы на самом деле переместили перечисляемый вперед на 10.
Возможно, лучше всего использовать расширение Linq Take()
. Я не думаю, что вам нужно использовать Skip()
с генератором.
Редактировать: Черт, я пытался проверить это поведение с помощью следующего кода
Примечание: это не совсем правильно, я оставляю это здесь, чтобы другие не впали в ту же ошибку.
var numbers = RandomNumberGenerator();
var slice = numbers.Take(10);
public static IEnumerable<int> RandomNumberGenerator()
{
yield return random.Next();
}
, но Count()
для slice
всегда 1. Я также попытался запустить его через цикл foreach
, так как я знаю, что расширения Linq обычно лениво оцениваются, и он зацикливается только один раз. В итоге я сделал код ниже вместо Take()
, и он работает:
public static IEnumerable<int> Slice(this IEnumerable<int> enumerable, int size)
{
var list = new List<int>();
foreach (var count in Enumerable.Range(0, size)) list.Add(enumerable.First());
return list;
}
Если вы заметили, что я добавляю First()
в список каждый раз, но так как передаваемое перечисляемое значение является генератором из RandomNumberGenerator()
, то результат каждый раз будет другим.
Так что снова с генератором, использующим Skip()
, не нужно, так как результат будет другим. Цикл по IEnumerable
не всегда свободен от побочных эффектов.
Редактировать: Я оставлю последнее редактирование только для того, чтобы никто не впал в ту же ошибку, но у меня все получилось, просто сделав это:
var numbers = RandomNumberGenerator();
var slice1 = numbers.Take(10);
var slice2 = numbers.Take(10);
Два ломтика были разные.