2

Say I have a ListA. I want to make a duplicate ListB so when I use ListB.Remove(SomeItem); it would not affect the listA.

The list items should refer to the same objects.

Since this is being used in a loop it is important to use least resource demanding approach. But I don't know how to do this in most efficient way.

Saeid
  • 691
  • 7
  • 26
  • Are the objects reference types, or value types? – Wai Ha Lee Jan 25 '16 at 11:02
  • I think the LINQ library supports a function that is called Copy(). But basically you can just create new List () and then iteratively add each element in ListA to the new list. Or just juse newList.AddRange(listA) – Glubus Jan 25 '16 at 11:02
  • 1
    Possible duplicate of [Deep copy of List](http://stackoverflow.com/questions/4226747/deep-copy-of-listt) – MakePeaceGreatAgain Jan 25 '16 at 11:03
  • What should happen when you modify `someItem` instead of deleting it? Should the change be reflected in both lists? – MakePeaceGreatAgain Jan 25 '16 at 11:04
  • It's a duplicate question... Anyways. Why don't you create two lists initially and add items to list 'B' along with list 'A'? –  Jan 25 '16 at 11:04

4 Answers4

7

You want a shallow clone, which you can do simply using this List<T> constructor:

var shallowClone = new List(originalList);

Note that the implementation of this constructor checks if originalList supports the Count property, and if it does it uses it to pre-size the list to avoid unnecessary memory allocations. This makes it pretty optimal:

_items = new T[count];
c.CopyTo(_items, 0);
_size = count;

However, I've looked at the implementation of Enumerable<T>.ToList() and all it does is call the List<T> constructor above.

So this code does pretty much exactly the same thing (and will run at the same speed):

var shallowClone = originalList.ToList();
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
3

You can simply call ListB.ToList() which will create a new list from ListB sharing the same elements. Changes to the element-SET of ListB are not reflected in A, however if you change any element it is reflected in both lists.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
2

In your case u can use List Generic Method. Add this method in your class.

public static List<T> Clone<T>(this List<T> myList)
{
    var newList = new List<T>(myList.Capacity);
    newList.AddRange(myList);
    return newList;
}
rdn87
  • 739
  • 5
  • 18
1

Interestingly, no one seems to be looking for a specialized List<T> method (which by definition should have an optimal implementation), and there is one called GetRange which according to the documentation

Creates a shallow copy of a range of elements in the source List<T>.

So creating a shallow copy of the whole source list would be something like this

var shallowClone = originalList.GetRange(0, originalList.Count);

P.S. Of course the difference in performance from the most concise

var shallowClone = originalList.ToList();

and not so concise

var shallowClone = new List<MyLongListItemType>(originalList);

will be negligible.

So I would personally prefer ToListversion, and at the same time will remember to not call ToList in my code without a need (which I've seen in many places) because of the copy behavior of that method.

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343