Допустим, у меня есть коллекция из 100 элементов. Обычный счетчик будет перебирать эти 100 элементов.
Я хотел бы создать перечислитель (который основан на обычном перечислителе, т.е. он не для каждой коллекции, а скорее для одного общего подхода), область действия которого от хе-хе до туда - и я мог бы, например, перебрать более 20 элементов в только середина.
void foo(IEnumerable<int> coll)
{
var regular_iter = coll.GetEnumerator();
regular_iter.MoveNext();
regular_iter.MoveNext();
// ... 8 more
var scoped_iter = new ScopeEnumerator(regular_iterator,20);
Поэтому в таком случае, когда я вызываю scoped_iter.Reset(), он сбрасывается до своего 0-го элемента (10-й для всей коллекции).
А также он видит только элементы от 10 до 30.
Вопрос в том -- как реализовать такой счетчик?
Редактировать
1.
Мне нужен итератор отсюда, а не оттуда, потому что добраться туда может занять очень много времени. Однако на самом деле это мелочи, наиболее проблематичным является метод сброса.
2.
Джон спросил о фоне. Чего я действительно пытаюсь добиться, так это нарезать коллекцию (т.е. у вас есть, скажем, коллекция из 10 строк, но вы хотели бы интерпретировать ее как коллекцию из 5 элементов, каждый из которых представляет собой коллекцию из 2 строк). Наивный алгоритм довольно прост, но и очень неэффективен. С коллекцией ~16MB (список строк) я думал о другом подходе - просто переинтерпретировать данные, не копируя их. Поэтому я бы создал один итератор, который выбирает каждый элемент SIZE_OF_SLICE из всей коллекции, а также я бы создал этот итератор с ограниченной областью действия, который будет начинаться с первого итератора и переходить к элементам SIZE_OF_SLICE.
Таким образом, данные будут повторно использоваться на месте, единственная разница будет заключаться в том, как вы их перебираете. Этого достаточно для нарезки, и она должна быть быстрой.
3
Я реализовал эффективную нарезку для IList (как только вы предполагаете, что у вас есть индексатор, это кусок пирога), но это беспокоит меня, вы не можете (?) Предоставить общий эффективный алгоритм как для списка (LinkedList), так и для массивов (List). Поэтому, если вы читаете это и у вас есть идея, как это сделать, не стесняйтесь отвечать даже через 10 лет (при условии, что C# все еще будет с нами).