我遇到了这段代码的麻烦。我是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中的每一行,它会将每一行的数据添加到列表中。 IE,字典中的最后一项将包含该范围内所有行的每个属性。我尝试在每次迭代后清除列表,但是字典报告没有值,这使我相信我必须为每个字典条目创建一个单独的列表?我怎么能这样做,这是最有效的方式吗?似乎有些东西。谢谢!
答案 0 :(得分:4)
看起来代码中只有一个列表,并且对它的引用存储为每个字典键的值。您希望在每次循环迭代时创建一个新List并将其添加到字典中。
答案 1 :(得分:1)
您不太了解的问题是List<T>
是引用类型。这意味着当您将其存储在某个位置时,无论是类中的属性还是Dictionary<TKey,List<T>>
中的值,任何更改都会影响保存引用的每个位置中的该列表。例如:
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);
}
这与你想要做的有些接近。
但如果你把输出写出来:
foreach (var kvp in dict)
{
Console.WriteLine("Key: {0}", kvp.Key);
foreach (var item in kvp.Value)
{
Console.WriteLine(" Value: {0}", item);
}
}
如果我正确地读到了你的期望,我认为你认为这将会出现:
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
这是因为您要将相同的列表添加到每个键的字典中,并且无论何时进行更改,都可以添加新值或清除它(使用{{1} }),您正在更改同一列表的每个匹配项。
答案 2 :(得分:0)
Dictionary
不是引用,但在这种情况下,包含引用。
Lists
也不是'引用',但它们是通过引用访问和操作的。如果您向某个内容添加List
,则会添加对该List
的引用,而不是副本。
通常只有在明确指定要复制或创建新实例时才会复制引用类型。
答案 3 :(得分:-1)
Dictionary<string, List<string>>
应该是字典。你的代码应该有效。如果字典有密钥,.Add将抛出异常。确保字典不在循环中。