【问题标题】:How to preserve lists already created before using List.Clear()如何在使用 List.Clear() 之前保留已创建的列表
【发布时间】:2014-09-18 11:50:08
【问题描述】:

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

这是我所说的一个例子。假设我制作了 2 个这样的列表:

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

}

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

【问题讨论】:

  • 好像你想复制列表。您可以轻松地使用.ToList() 创建具有相同元素的新列表。
  • 好吧,我不想复制列表,每次都有不同的数据。我的例子只是试图解释这种情况
  • 实际上,不要这样做list.Clear(),因为无论如何您每次迭代都会创建一个新列表。那你为什么要清除当前的?
  • @YoryeNathan 在第二个代码块中创建一个新列表,但我想避免这条路线。在第一个代码块中,它不是创建一个新列表,而是添加到同一个列表中,然后清除它。
  • list2列表的列表。当您list2.Add(list) 时,您正在向list2 的内容添加list引用。无论您如何访问它,随后对 list 所做的任何更改都将显而易见,例如通过listlist2[0] 查看它。

标签: c# asp.net


【解决方案1】:

类通过引用传递,List&lt;T&gt; 是一个类。因此,当您清除 list 时,它也会清除 list2 中通过引用传递的数据。详情请见List - do I pass objects or references?

这应该可以解决您的示例中显示的问题,并在清除 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();

}

另请参阅 Jon Skeet 的 Parameter passing in C#,了解有关如何在 C# 中传递参数的更广泛信息,尤其是与引用类型相关的信息。

【讨论】:

    【解决方案2】:

    您的解决方法不是解决方法;这是正确的做法。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 2014-07-25
      • 2011-11-21
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多