10

Is this the only way of passing a List to a method and editing that List, without modifying the original List?

class CopyTest1
{
    List<int> _myList = new List<int>();
    public CopyTest1(List<int> l)
    {
        foreach (int num in l)
        {
            _myList.Add(num);
        }
        _myList.RemoveAt(0); // no effect on original List
    }
}
Paligulus
  • 493
  • 1
  • 4
  • 14
  • Is this `a` way of passing a List to a method and editing that List, without modifying the original List? – Bastardo Oct 10 '11 at 12:39

6 Answers6

18

duplicate the list:

_myLocalList = new List<int>(_myList);

and perform the operations on the local list.

Andreas
  • 6,447
  • 2
  • 34
  • 46
6

Use AsReadOnly for this:

class CopyTest1
{
    List<int> _myList = new List<int>();
    public CopyTest1(IList<int> l)
    {
        foreach (int num in l)
        {
            _myList.Add(num);
        }
        _myList.RemoveAt(0); // no effect on original List
    }
}

And call it via CopyTest1(yourList.AsReadOnly()) .

Yahia
  • 69,653
  • 9
  • 115
  • 144
3

There is another way. You can use the copy constructor of List<T>:

List<int> _myList;
public CopyTest1(List<int> l)
{
    _myList = new List<int>(l);
}
Ilian
  • 5,113
  • 1
  • 32
  • 41
1

Clone objects in the list to other list and work on this copy

static class Extensions
{
        public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
        {
                return listToClone.Select(item => (T)item.Clone()).ToList();
        }
}
Saint
  • 5,397
  • 22
  • 63
  • 107
0

When you pass a list to a method you pass a pointer to said list, that's why your changing the 'original' list when you modify it inside your method. If you instead want to modify a copy of the list you just need to make one. In the code that calls CopyTest1 you can create a new list based on your original list:

public void CallsCopyTest1()
{
    var originalList = new List<int>();
    var newList = new List<int>(originalList);
    var copyTest = new CopyTest1(newList); //Modifies newList not originalList
}
class CopyTest1
{
    List<int> _myList = new List<int>();
    public CopyTest1(List<int> l)
    {
        foreach (int num in l)
        {
            _myList.Add(num);
        }
        _myList.RemoveAt(0); // no effect on original List
    }
}
Simon Stender Boisen
  • 3,413
  • 20
  • 23
  • If the callers forgets to create a copy then they will get unexpected behaviour - I would prefer for the class\method to handle it – Paligulus Oct 10 '11 at 12:47
  • That depends what the purpose of the class is, is it do modify a collection or to create a copy of a collection and modify it? The example is a bit contrived and I don't think it's obvious exactly what you wanted. – Simon Stender Boisen Oct 10 '11 at 12:52
-1

You can pass an object by reference doing the following:

public static void ReferenceMethod(ref List<T> myParam) {
    ...
} 

EDIT: The question has now been clarified, the OP was after a way not to alter the original list.

dougajmcdonald
  • 19,231
  • 12
  • 56
  • 89
  • and in any case it is not necessary to pass it as `ref` to alter the original list -- `ref` allows you to change the reference in the caller's scope to point to another object, something that is highly unlikely to be useful – newacct Oct 11 '11 at 04:29