2

I have a List with a large amount of elements in it. I need to create a copy of this list to perform operations on it without altering the original list. However, the operations typically only access a small proportion of the elements of the list, and so it is inefficient to copy the entire thing when most of it will go unused. Is there a simple way to create an object which is a clone of a list, but only clones elements when they are accessed? I have looked into the Lazy<T> class, which seems to be what I want, but I don't know how to apply it in this situation.

I want to be able to do something like this:

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

And this:

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

I don't mind if the solution isn't generic enough to handle Lists of any type; I would be fine with it being specific to one or two classes I've created.

Preferably this would be a deep copy rather than a shallow copy, but a shallow copy would still be useful, and I would appreciate examples of that if it is shorter/simpler too.

Strigoides
  • 4,329
  • 5
  • 23
  • 25
  • 4
    You could use LINQ which is lazy by nature. Then you don't have to create a copy at all (if you don't want). – Tim Schmelter Oct 17 '12 at 07:41
  • @TimSchmelter So, if I use something like `IEnumerable lazyClone = myList.Select(element => element.Clone())`, elements in `lazyClone` are only cloned as they are accessed? – Strigoides Oct 17 '12 at 07:43
  • @Strigoides exactly, `lazyClone` query will be executed when you start using it – Sergey Berezovskiy Oct 17 '12 at 07:45
  • @TimSchmelter I see. In this case, I do have to create copies of the list and modify it. – Strigoides Oct 17 '12 at 07:47
  • Yes, but the question is if you need to create a clone at all. Do you have an example of what you're trying to do? – Tim Schmelter Oct 17 '12 at 07:47
  • The application here is a MiniMax implementation, in which I have a `Game` object which needs to be cloned before performing the move that is being examined, so that the moves don't alter the original game object – Strigoides Oct 17 '12 at 07:49
  • So you have a `List` or the `Game` contains a list? If the former, why are you worried about cloning the list itself - just pick a `Game` from the list, clone the `Game`, and perform your checks on the clone. – Rawling Oct 17 '12 at 07:55
  • Fair enough, that makes more sense. – Rawling Oct 17 '12 at 07:58

1 Answers1

4

Sounds like you want to end up with your original list plus a sparse collection of overrides.

Why not create a dictionary for the overrides, keyed on the index into the original list? You can then manually add values from your original list as they are needed.

You could wrap this functionality up into a class that wraps IList<T> if it's something you're going to use often.

Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93