C# dictionary value clearing out when I clear list

2020-01-27 07:38发布

Dictionary <string, List <SaleItem>> saleItemNew = new Dictionary<string, List<    SaleItem>> ();

saleItems = new List <SaleItem> ();

saleItemNew.Add("1", saleItems);

At this point the list in the Dictionary has values.

saleItems.Clear();

However, when I clear out the list previously assigned to it, the dictionary's value List is now empty...why?

标签: c# dictionary
6条回答
放我归山
2楼-- · 2020-01-27 08:18

The reason is that Dictionary is a reference and not a value type. When you assign a Dictionary to another variable it does not perform a deep copy. Instead it just points another reference at the same object. Since there is only one object, clearing via either reference will be visible to both references.

This in contrast to value types in the .Net Framework. Assignment of a value type essentially performs a shallow copy of the data and creates two independent objects. Note, that if the value type has a reference field, the two field in the two value types will still point to the same object.

查看更多
Luminary・发光体
3楼-- · 2020-01-27 08:18

It uses the same reference.

A better way to do it is

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

And for clearing

saleItemNew["1"] = new List<SaleItem>(); 
查看更多
放荡不羁爱自由
4楼-- · 2020-01-27 08:20

As it is a reference type, just the pointer to the values in memory is copied not the values themselves. You can specifiy the behaviour you want with a constructor:

From dot net perls: // // Copy the Dictionary to a second object. // Dictionary copy = new Dictionary(dictionary);

查看更多
别忘想泡老子
5楼-- · 2020-01-27 08:21

it has to do with memory usage and pointers. You have a stack, and a heap when allocating memory for objects, that memory is one the heap. Your saleItems variable is defined on the stack and points to the memory address on the heap. Your Dictionary is also on the stack pointing at the heap.

when you say:

saleItems = new List<SaleItem>()

the variable saleItems is pushed onto the stack and contains a memory address the points to the location of the data on the heap. Lets say 0x0100. Now you add a new DictionaryItem to your dictionary. The DictionaryItem is placed on the heap with two properties, Key and Value. In this case, you have added saleItems as Value, so Value has the address 0x0100 as well. Now DictionaryItem.Value is pointing at the same memory as saleItems. When you call saleItems.Clear, you are saying find the list at address 0x0100 and remove all items. So the dictionary and the variable both become empty because they are pointing at the same memory. What you want to do is say saleItems = new List<SaleItem>(); again. Now saleItems will point to a new address on the heap (say 0x0200). DictionaryItem.Value is still pointing at memory address 0x0100 so you can act on the saleItems variable without affecting the data in your dictionary.

For more information on stacks and heaps in c# try this article: http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-98b5-413b6d348b91

查看更多
▲ chillily
6楼-- · 2020-01-27 08:22

Adding the List to the dictionary is just a shallow copy... A new list with the same values is not created and added (a deep copy); rather a reference to the old list is added.

查看更多
Root(大扎)
7楼-- · 2020-01-27 08:25

The dictionary contains the same reference to the list, so modifying the list will change both references.

Microsoft documentation about reference types: http://msdn.microsoft.com/en-us/library/490f96s2.aspx

查看更多
登录 后发表回答