如何保留在使用List.Clear()之前已创建的列表



当我将数据添加到List,然后将该列表附加到另一个列表,然后在原始列表上使用List.Clear()时,它会清空所有内容,并且已经附加的列表不会保留。

下面是我所说的一个例子。比方说我做了两个这样的列表:

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();
}

当我运行list.Clear()时,它会清除我已经附加到list2 的所有预先存在的列表

我知道一个变通办法是重新排列代码,如下所示:

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);
}

但这种行为正常吗?是否可以保留预先附加的列表?

类通过引用传递,List<T>是一个类。因此,当您清除列表时,它也会清除列表2中通过引用传递的数据。请参阅列表-我传递对象还是引用?了解更多详细信息。

这将解决示例中显示的问题,并在清除list:之前创建list的新副本以添加到list2

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();
}

有关如何在C#中传递参数,特别是与引用类型有关的参数,请参阅Jon Skeet的C#中的参数传递。

你的变通办法不是变通办法;这是正确的做法。

List是一个对象,因此是一个引用类型。您的list是一个整数值列表;您的list2是对整数列表的引用列表。

调用list.ToList()之所以有效,是因为该方法返回了一个新列表。来源:

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

这里有一些代码来说明值类型列表引用类型列表间的区别:

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; }
}

输出:

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

最新更新