【问题标题】:MyList = new List<int>(); works, but MyList.Clear(); doesn't [duplicate]MyList = new List<int>();有效,但 MyList.Clear();不[重复]
【发布时间】:2017-03-04 00:27:48
【问题描述】:

我不确定我是否遗漏了什么,但以下代码不会产生我预期的输出,除非我将行 TheList.Clear(); 更改为 TheList = new List&lt;int&gt;();

     List<List<int>> ListOfLists = new List<List<int>>();
     List<int> TheList = new List<int>();

     for (int i = 1; i <= 30; i++)
     {
        TheList.Add(i);

        if (TheList.Count < 10)
           Console.WriteLine(i.ToString() + " adicionado");
        else
        {
           ListOfLists.Add(TheList);
           TheList.Clear(); // THIS
        }
     }

     string AllItems = "";

     for (int i = 0; i < ListOfLists.Count; i++)
     {
        foreach (int j in ListOfLists[i])
           AllItems += j.ToString() + ",";

        AllItems += "/";
     }

     Console.WriteLine(AllItems);

当实例化一个新列表时,我得到

"1,2,3,4,5,6,7,8,9,10,/11,12,13,14,15,16,17,18,19,20,/21,22,23,24,25,26,27,28,29,30,/"

作为输出,但是当清除它时,输出是"///"

为什么会这样?

【问题讨论】:

  • 请说明您的要求。

标签: c# .net list


【解决方案1】:

这并不像你认为的那样:

ListOfLists.Add(TheList);

当您创建TheList 的实例时,内存中有一个这样的列表。当您将TheList 添加到ListOfLists 时,内存中仍然只有一个该原始列表。上面这行代码不会创建副本。

所以当你这样做时:

TheList.Clear();

您对内存中的那个 一个 列表执行清除操作。任何包含对该列表的引用的代码(例如ListOfLists 中的元素)都将能够观察到该更改。那一个列表已被清除。

但是,当你这样做时:

TheList = new List<int>();

您在内存中创建一个新的单独 列表,然后简单地将变量TheList 更改为指向新列表而不是原始列表。如果没有其他对原始列表的引用,垃圾收集器会将其从内存中清除。但是,仍然有参考。它是ListOfLists 中的一个元素。因此,在上述行之后,您现在在内存中有 两个 列表。您对这个新列表执行的任何操作都不会影响原始列表。

【讨论】:

    【解决方案2】:

    这一行:

    ListOfLists.Add(TheList);
    

    实际上是向 TheList 添加了一个引用,而不是它的副本。所以当你这样做时

    TheList.Clear();
    

    您还清除了存储在 ListOfLists 中的同一个列表。

    我建议您不需要Clear(),而只需每次都声明 TheList 一个新列表:

     List<List<int>> ListOfLists = new List<List<int>>();
     List<int> TheList = new List<int>();
    
     for (int i = 1; i <= 30; i++)
     {
        TheList.Add(i);
    
        if (TheList.Count < 10)
           Console.WriteLine(i.ToString() + " adicionado");
        else
        {
           ListOfLists.Add(TheList);
           TheList = new List<int>();
        }
     }
    

    【讨论】:

      【解决方案3】:

      我会尽量回答这个问题。 当您将 TheList 添加到 ListOfLists 时,您正在将 TheList 的引用(内存位置)添加到 ListofLists。因此,如果您使用 clear,则在循环结束时,您将在 ListOfLists 中有 3 个空列表,因为您已清除 TheList 引用 3 次;每个 ListOfLists 单元格都包含对同一列表的引用。

      在这样的循环中,您需要添加一个新列表。添加新列表将为您创建的每个列表创建单独的参考。如果您清除其中的一个,它将不会清除另一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-15
        • 2015-08-16
        • 2018-02-25
        • 2015-07-01
        • 2017-02-19
        • 2019-05-03
        • 2017-10-17
        • 1970-01-01
        相关资源
        最近更新 更多