How to keep lists already created before using List.Clear ()

When I add data to List

, add this list to another list, then use List.Clear()

in the original list, it empties everything and the already added lists will not be saved.

Here's an example of what I'm talking about. Let's say I made 2 lists:

List<int> list = new List<int>();
List<List<int>> list2 = new List<List<int>>();

for(int i=0;i<10;i++){

  for(int i2=0;i2<10;i2++){
    list.Add(i2);
  }
  list2.Add(list);
  list.Clear();

}

      

When I run List.Clear()

it clears all the pre-existing lists that I have already added tolist2

I know the job would be to reorder the code like this:

List<List<int>> list2 = new List<List<int>>();

for(int i=0;i<10;i++){

  List<int> list = new List<int>(); //<- moved inside the for

  for(int i2=0;i2<10;i2++){
    list.Add(i2);
  }
  list2.Add(list);

}

      

But is this normal behavior? Is it possible to keep pre-added lists?

+3


source to share


2 answers


Classes are passed by reference, and List<T>

is a class. Accordingly, when you clear the list, it also clears the data passed by reference in list2. See List for more details - pass objects or references? ...

This should solve the problem shown in your example and create a new copy list

to append to list2

before cleaning up list

:



List<int> list = new List<int>();
List<List<int>> list2 = new List<List<int>>();

for(int i=0;i<10;i++){

  for(int i2=0;i2<10;i2++){
    list.Add(i2);
  }
  list2.Add(list.ToList()); //modified to create a new List when adding
  list.Clear();

}

      

See also Jon Skeet Passing Parameters in C # for more details on how parameters are passed in C #, especially regarding reference types.

+4


source


Your work around doesn't work; what is the correct way to do it.

A list is an object and therefore a reference type. Yours list

is a list of integer values; your list2

is a list of references to lists of integers.

The call list.ToList()

works because this method returns a new list. From source:

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
        return new List<TSource>(source);
}

      



Here's some code to illustrate the difference between a list of value types and a list of reference types :

void Main()
{
    int x = 0, y = 1, z = 2;

    var list = new List<int> { x, y, z };
    list.ForEach(i => Console.WriteLine(i));

    x = y = z = 0;
    list.ForEach(i => Console.WriteLine(i));

    WorseInt a = new WorseInt { Value = 0 },
        b = new WorseInt { Value = 1 },
        c = new WorseInt { Value = 2 };

    var worseList = new List<WorseInt> { a, b, c };
    worseList.ForEach(i => Console.WriteLine(i.Value));

    a.Value = b.Value = c.Value = 0;
    worseList.ForEach(i => Console.WriteLine(i.Value));
}

public class WorseInt
{
    public int Value { get; set; }
}

      

Output:

0
1
2
0
1
2
0
1
2
0
0
0

      

0


source







All Articles