循环后不保存List <string>

时间:2018-10-09 13:03:15

标签: c#

我正试图找出为什么 dataItems List<List<string>>在循环后没有保存的原因。当我对其进行调试时,它会添加到 dataItemsList List<string>中,每一个都具有3个值和6个迭代(按预期)。

离开for循环后,它只有6个空列表。

            List<List<string>> dataItems = new List<List<string>>();
            List<string> dataItemsList = new List<string>();

            for (int i = 0; dataReader.Read(); i++)
            {
                int j = 0;
                for (j = 0; j < dataReader.FieldCount; j++)
                {
                    dataItemsList.Add(dataReader[j].ToString());
                }
                dataItems.Add(dataItemsList);
                dataItemsList.Clear();
            }
            Console.WriteLine(dataItems);

还有更多代码,但我希望它是更本地化的,因为值是在循环内分配的,而变量是在外部声明的。

2 个答案:

答案 0 :(得分:6)

您正在清除列表! (dataItemsList.Clear();

您可能要创建一个新实例,而不是清除列表:

while (dataReader.Read())
{
    List<string> dataItemsList = new List<string>();

    for (int j = 0; j < dataReader.FieldCount; j++)
    {
        dataItemsList.Add(dataReader[j].ToString());
    }

    dataItems.Add(dataItemsList);
}

Console.WriteLine(dataItems);

答案 1 :(得分:1)

对于引用类型在C#中的工作方式似乎存在误解。

调用dataItems.Add(dataItemsList)时,您要做的是向dataItemsList所在的位置添加一个新引用(指向内存堆的指针)。如果然后调用Clear(),则表示您正在修改集合的内容,这与dataItems[0]所指向的内容相同。然后,当您重复循环时,将再次添加到同一实例并再次清除它。最后,您将获得指向单个dataItemsList的指针的集合,这些指针最终将为空。

这就是为什么您必须在循环开始时通过调用List<string> dataItemsList = new List<string>();实例化一个新实例(在内存堆中创建新列表),而不必在末尾Clear实例化。

将引用类型想象为仅指向某个位置的指针(箭头)非常有帮助。它们不直接包含数据,分配它们不会复制任何内容,只会使箭头指向特定的内存地址。