簡體   English   中英

當我清除以前分配給它的列表時,C#詞典值就會清除……為什么?

[英]C# dictionary value clearing out when I clear list previously assigned to it…why?

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

saleItems = new List <SaleItem> ();

saleItemNew.Add("1", saleItems);

此時,詞典中的列表具有值。

saleItems.Clear();

但是,當我清除先前分配給它的列表時,字典的值List現在為空...為什么?

詞典包含對列表的相同引用,因此修改列表將同時更改兩個引用。

有關參考類型的Microsoft文檔: http : //msdn.microsoft.com/zh-cn/library/490f96s2.aspx

原因是Dictionary是引用而不是值類型。 將字典分配給另一個變量時,它不會執行深度復制。 相反,它只是將另一個引用指向同一對象。 由於只有一個對象,因此通過兩個引用進行清除對於兩個引用都是可見的。

與.Net Framework中的值類型相反。 值類型的分配實際上執行數據的淺表復制並創建兩個獨立的對象。 請注意,如果值類型具有引用字段,則兩種值類型中的兩個字段仍將指向同一對象。

它與內存使用情況和指針有關。 在為對象分配內存時,您有一個堆棧和一個堆,該內存是一個堆。 您的saleItems變量在堆棧上定義,並指向堆上的內存地址。 您的字典也位於指向堆的堆棧上。

當你說:

saleItems = new List<SaleItem>()

變量saleItems被壓入堆棧,並包含指向堆上數據位置的內存地址。 假設0x0100 現在,您將新的DictionaryItem添加到字典中。 DictionaryItem通過兩個屬性Key和Value放置在堆上。 在這種情況下,您已將saleItems添加為Value ,因此Value的地址也為0x0100 現在, DictionaryItem.Value指向與saleItems相同的內存。 當您調用saleItems.Clear時,是說在地址0x0100處找到列表並刪除所有項目。 因此,字典和變量都變為空,因為它們指向相同的內存。 您想要做的是說saleItems = new List<SaleItem>(); 再次。 現在,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 <string, List <SaleItem>> saleItemNew = new Dictionary<string, List<SaleItem>>();
saleItemNew.Add("1", new List<SaleItem>());

並進行清算

saleItemNew["1"] = new List<SaleItem>(); 

由於它是引用類型,因此僅復制指向內存中值的指針,而不復制值本身。 您可以使用構造函數指定所需的行為:

從dot net perls:// //將Dictionary復制到第二個對象。 //字典副本=新字典(dictionary);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM