C#:使用列表作为字典值。值不会存储在字典中

C#:使用列表作为字典值。值不会存储在字典中,c#,list,dictionary,C#,List,Dictionary,我在这段代码上遇到了问题。我对C#还不熟悉,但从我迄今为止所做的工作来看,我得出的结论是,字典只是引用,实际上并不存储数据 foreach (Microsoft.Office.Interop.Excel.Range row in range1.Rows) { string upc; upc = row.Cells[1, 2].Value2; list.Ad

我在这段代码上遇到了问题。我对C#还不熟悉,但从我迄今为止所做的工作来看,我得出的结论是,字典只是引用,实际上并不存储数据

           foreach (Microsoft.Office.Interop.Excel.Range row in range1.Rows)
            {
                string upc;
                upc = row.Cells[1, 2].Value2;
                list.Add(upc);
                list.Add(row.Cells[1, 3].Value2);
                list.Add("6");


                //add row to dictionary
                dictionary.Add(row.Cells[1, 1].Value2, list);
}


在本例中,如果我对range1中的每一行保持此循环,它会将每一行的数据添加到列表中。即,字典中的最后一项将包含范围中所有行的每个属性。我尝试在每次迭代后清除列表,但是字典报告没有值,这让我相信我必须为每个字典条目创建一个单独的列表?我怎样才能做到这一点,这是最有效的方法吗?好像有什么不对劲。谢谢

代码中似乎只有一个列表,对它的引用存储为每个字典键的值。您希望在每次循环迭代时创建一个新列表,并将其添加到字典中。

代码中似乎只有一个列表,对它的引用存储为每个字典键的值。您希望在每次循环迭代时创建一个新列表,并将其添加到字典中。

字典应为字典。你的代码应该可以工作。如果字典具有该键,则.Add将引发异常。确保字典在循环之外。

字典应为字典。你的代码应该可以工作。如果字典具有该键,则.Add将引发异常。确保字典在循环之外。

字典
不是引用,但在本例中它包含引用

列表
也不是“引用”,但它们是通过引用访问和操作的。如果向某个内容添加
列表
,则会添加对该
列表
的引用,而不是副本


引用类型通常仅在您明确指定要复制或创建新实例时才被复制。

字典
不是引用,但在本例中它包含引用

列表
也不是“引用”,但它们是通过引用访问和操作的。如果向某个内容添加
列表
,则会添加对该
列表
的引用,而不是副本


通常,只有当您明确指定要复制或创建新实例时,才会复制引用类型。

您没有完全理解的问题是
List
是引用类型。这意味着当您将其存储在某个位置时,无论是类中的属性还是
字典中的值,任何更改都将影响保存引用的每个位置中的列表。例如:

List<String> list = new List<String>();
Dictionary<Int32, List<String>> dict = new Dictionary<Int32, List<String>>();

for (int i = 0; i < 3; i++)
{
    list.Add("String" + i);
    dict.Add(i, list);
}
如果我正确地理解了你的期望,我认为你会这样想:

Key: 0
    Value: String0
Key: 1
    Value: String0
    Value: String1
Key: 2
    Value: String0
    Value: String1
    Value: String2
Key: 3
    Value: String0
    Value: String1
    Value: String2
    Value: String3
但实际产出是:

Key: 0
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 1
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 2
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 3
    Value: String0
    Value: String1
    Value: String2
    Value: String3

这是因为您正在为每个键向字典中添加相同的列表,并且无论何时进行更改,无论是添加新值还是清除它(使用
List.clear()
),您都在更改相同列表的每次出现。

您没有完全理解的问题是
List
是一种引用类型。这意味着当您将其存储在某个位置时,无论是类中的属性还是
字典中的值,任何更改都将影响保存引用的每个位置中的列表。例如:

List<String> list = new List<String>();
Dictionary<Int32, List<String>> dict = new Dictionary<Int32, List<String>>();

for (int i = 0; i < 3; i++)
{
    list.Add("String" + i);
    dict.Add(i, list);
}
如果我正确地理解了你的期望,我认为你会这样想:

Key: 0
    Value: String0
Key: 1
    Value: String0
    Value: String1
Key: 2
    Value: String0
    Value: String1
    Value: String2
Key: 3
    Value: String0
    Value: String1
    Value: String2
    Value: String3
但实际产出是:

Key: 0
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 1
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 2
    Value: String0
    Value: String1
    Value: String2
    Value: String3
Key: 3
    Value: String0
    Value: String1
    Value: String2
    Value: String3

这是因为您正在为每个键向字典中添加相同的列表,并且无论何时进行更改,无论是添加新值还是清除它(使用
List.clear()
),您都在更改相同列表的每次出现。

我感到困惑。您是希望列表是每个单元格的聚合,还是这样做而您不希望它这样做?关于字典为空的部分对我来说毫无意义,除非你抛出了一个异常,并且它从未向字典添加任何内容。您确定row.Cells[x,y].Value2实际返回了所需的数据吗?我记不清了,但新的.NET MS Office库似乎将缓存中的单元格值与单元格分开,因此您必须从单元格中取出一个引用,并与值表交叉引用。不要介意我对MS Office库的评论。你用的是旧的互操作系统,我很困惑。您是希望列表是每个单元格的聚合,还是这样做而您不希望它这样做?关于字典为空的部分对我来说毫无意义,除非你抛出了一个异常,并且它从未向字典添加任何内容。您确定row.Cells[x,y].Value2实际返回了所需的数据吗?我记不清了,但新的.NET MS Office库似乎将缓存中的单元格值与单元格分开,因此您必须从单元格中取出一个引用,并与值表交叉引用。不要介意我对MS Office库的评论。你正在使用旧的互操作系统。好吧,这是我想听到的,因为它证实了我的想法。在这种情况下,我如何在每次循环迭代开始时创建一个新列表..如果列表的数量是动态的,并且每次程序运行时都会更改?list lst=newList@user1739730在“list.Add(upc);”行之前添加“list=new list();”好的,这是我想听到的,因为它证实了我的想法。在这种情况下,我如何在每次循环迭代开始时创建一个新列表..如果列表的数量是动态的,并且每次程序运行时都会更改?list lst=newList@user1739730在带有“list.Add(upc);”的行之前添加“list=newlist();”,字典在循环之外。列表被添加到字典中很好,只是如果我在每次迭代中清除列表,那么特定键的字典值就消失了(即使我清除了它)