当我清除先前分配给它的列表时,C#字典值清除…为什么?

Dictionary <string, List > saleItemNew = new Dictionary<string, List> (); saleItems = new List  (); saleItemNew.Add("1", saleItems); 

此时,Dictionary中的列表具有值。

 saleItems.Clear(); 

但是,当我清除以前分配给它的列表时,字典的值列表现在为空……为什么?

字典包含对列表的相同引用,因此修改列表将更改两个引用。

有关引用类型的Microsoft文档: http : //msdn.microsoft.com/en-us/library/490f96s2.aspx

原因是Dictionary是引用而不是值类型。 将词典分配给另一个变量时,它不执行深层复制。 相反,它只是指向同一对象的另一个引用。 由于只有一个对象,因此两个引用都可以看到通过任一引用清除。

这与.Net Framework中的值类型形成对比。 值类型的赋值实质上执行数据的浅表副本并创建两个独立对象。 请注意,如果值类型具有引用字段,则两个值类型中的两个字段仍将指向同一对象。

它与内存使用和指针有关。 在为对象分配内存时,您有一个堆栈和一个堆,该内存是堆中的一个。 您的saleItems变量在堆栈上定义,并指向堆上的内存地址。 你的字典也在堆栈上指向堆。

当你说:

 saleItems = new List() 

变量saleItems被压入堆栈并包含一个内存地址,指向堆上数据的位置。 可以说是0x0100 。 现在,您将新的DictionaryItem添加到字典中。 DictionaryItem放在堆上,具有两个属性Key和Value。 在这种情况下,您已将saleItems添加为Value ,因此Value也具有地址0x0100 。 现在, DictionaryItem.Value指向与saleItems相同的内存。 当您调用saleItems.Clear时,您要查找地址为0x0100的列表并删除所有项目。 因此字典和变量都变为空,因为它们指向相同的内存。 你想要做的是说saleItems = new List(); 再次。 现在,saleItems将指向堆上的新地址(比如0x0200 )。 DictionaryItem.Value仍指向内存地址0x0100因此您可以对saleItems变量执行操作,而不会影响字典中的数据。

有关c#中堆栈和堆的更多信息,请尝试以下文章: http ://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-98b5-413b6d348b91

将列表添加到字典只是一个浅层副本…不会创建和添加具有相同值的新列表(深层副本); 而是添加了对旧列表的引用。

它使用相同的参考。

更好的方法是

 Dictionary > saleItemNew = new Dictionary>(); saleItemNew.Add("1", new List()); 

并清理

 saleItemNew["1"] = new List(); 

因为它是一个引用类型,所以只复制指向内存中值的指针而不是值本身。 您可以使用构造函数指定所需的行为:

从dot net perls:// //将Dictionary复制到第二个对象。 // Dictionary copy = new Dictionary(dictionary);