我不确定我是否遗漏了某些内容,但以下代码不会产生我预期的输出,除非我将行TheList.Clear();
更改为TheList = new List<int>();
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,/"
作为输出,但清除时,输出为"///"
。
为什么会这样?
答案 0 :(得分:4)
这不符合你的想法:
ListOfLists.Add(TheList);
当您创建TheList
的实例时,内存中会有一个这样的列表。当您将TheList
添加到ListOfLists
时,内存中仍然只有一个原始列表。上面的代码行不会创建副本。
所以当你这样做时:
TheList.Clear();
您在内存中的 one 列表上执行清除操作。任何包含对该列表的引用的代码(例如ListOfLists
中的元素)都能够观察到该更改。那个单一的清单已被清除。
但是,当你这样做时:
TheList = new List<int>();
您在内存中创建一个新的单独的列表,只需将变量TheList
更改为指向新列表而不是原始列表。如果没有其他对原始列表的引用,它将由垃圾收集器从内存中清除。但是,仍然有人提到它。它是ListOfLists
中的一个元素。因此,在上面的行之后,您现在在内存中有两个列表。您在此新列表上执行的任何操作都不会影响原始列表。
答案 1 :(得分:1)
这一行:
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>();
}
}
答案 2 :(得分:1)
我会尽力回答这个问题。 将List添加到ListOfLists时,您将TheList的引用(内存位置)添加到ListofLists。所以,如果你使用clear,在你的循环结束时你将在ListOfLists中有3个空列表,因为你清除了TheList引用3次;每个ListOfLists单元格都保存对同一列表的引用。
在这样的循环中,您需要添加一个新列表。添加新列表将为您创建的每个列表创建单独的引用。如果你清楚这些,它将不会清除另一个。