Ленивый клон списка

У меня есть список с большим количеством элементов. Мне нужно создать копию этого списка, чтобы выполнять с ним операции, не изменяя исходный список. Однако операции обычно обращаются только к небольшой части элементов списка, поэтому неэффективно копировать все, когда большая часть не используется. Есть ли простой способ создать объект, который является клоном списка, но только клонирует элементы при доступе к ним? Я изучил класс Lazy<T>, который, кажется, мне нужен, но я не знаю, как его применить в этой ситуации.

Я хочу сделать что-то вроде этого:

LazyListCopy<SomeType> lazyCopy = LazyListCopy.Copy(myList); // No elements have been copied at this point
DoSomethingWith(lazyCopy[34]);                               // 35th element has now been copied

И это:

foreach(SomeType listElement in LazyCopy.Copy(myOtherList))
{
    if (!Check(listElement))   // Object corresponding to listElement has been cloned
        break;
}

Я не возражаю, если решение недостаточно универсальное для обработки списков любого типа; Я был бы доволен, если бы он был привязан к одному или двум созданным мной классам.

Предпочтительно это будет глубокая копия, а не мелкая, но мелкая копия все равно будет полезна, и я был бы признателен за примеры этого, если бы она была короче / проще.


person Strigoides    schedule 17.10.2012    source источник
comment
Вы можете использовать LINQ, который по своей природе ленив. Тогда вам вообще не нужно создавать копию (если вы не хотите).   -  person Tim Schmelter    schedule 17.10.2012
comment
@TimSchmelter Итак, если я использую что-то вроде IEnumerable<SomeType> lazyClone = myList.Select(element => element.Clone()), элементы в lazyClone клонируются только при доступе к ним?   -  person Strigoides    schedule 17.10.2012
comment
@Strigoides точно, lazyClone запрос будет выполнен, когда вы начнете его использовать   -  person Sergey Berezovskiy    schedule 17.10.2012
comment
@TimSchmelter Понятно. В этом случае мне нужно создать копии списка и изменить его.   -  person Strigoides    schedule 17.10.2012
comment
Да, но вопрос в том, нужно ли вообще создавать клон. У вас есть пример того, что вы пытаетесь сделать?   -  person Tim Schmelter    schedule 17.10.2012
comment
Приложение здесь представляет собой реализацию MiniMax, в которой у меня есть объект Game, который необходимо клонировать перед выполнением исследуемого хода, чтобы ходы не изменяли исходный игровой объект.   -  person Strigoides    schedule 17.10.2012
comment
Итак, у вас есть List<Game> или Game содержит список? Если первое, то почему вы беспокоитесь о клонировании самого списка - просто выберите Game из списка, клонируйте Game и выполните проверки на клоне.   -  person Rawling    schedule 17.10.2012
comment
Достаточно справедливо, это имеет больше смысла.   -  person Rawling    schedule 17.10.2012


Ответы (1)


Похоже, вы хотите закончить свой исходный список плюс редкую коллекцию переопределений.

Почему бы не создать словарь для переопределений, привязанный к индексу исходного списка? Затем вы можете вручную добавлять значения из исходного списка по мере необходимости.

Вы можете обернуть эту функциональность в класс, который будет оберткой IList<T>, если вы собираетесь ее часто использовать.

person Matthew Strawbridge    schedule 17.10.2012