Значение словаря C # очищается, когда я очищаю список, ранее назначенный ему .... почему? - PullRequest
1 голос
/ 18 июня 2009
Dictionary <string, List <SaleItem>> saleItemNew = new Dictionary<string, List<    SaleItem>> ();

saleItems = new List <SaleItem> ();

saleItemNew.Add("1", saleItems);

На данный момент список в словаре имеет значения.

saleItems.Clear();

Однако, когда я очищаю ранее назначенный ему список, значение словаря List теперь пусто ... почему?

Ответы [ 6 ]

11 голосов
/ 19 июня 2009

Словарь содержит одну и ту же ссылку на список, поэтому изменение списка изменит обе ссылки.

Документация Microsoft о справочных типах: http://msdn.microsoft.com/en-us/library/490f96s2.aspx

1 голос
/ 19 июня 2009

Причина в том, что словарь является ссылкой, а не типом значения. Когда вы назначаете словарь другой переменной, он не выполняет глубокое копирование. Вместо этого он просто указывает другую ссылку на тот же объект. Поскольку существует только один объект, очистка по любой из ссылок будет видима для обеих ссылок.

Это в отличие от типов значений в .Net Framework. Присвоение типа значения по существу выполняет поверхностную копию данных и создает два независимых объекта. Обратите внимание, что если тип значения имеет поле ссылки, два поля в двух типах значений по-прежнему будут указывать на один и тот же объект.

0 голосов
/ 06 июля 2011

Поскольку это ссылочный тип, копируется только указатель на значения в памяти, а не сами значения. Вы можете указать желаемое поведение с помощью конструктора:

из списка точек: // // Копируем словарь во второй объект. // Копия словаря = новый словарь (словарь);

0 голосов
/ 19 июня 2009

Используется та же ссылка.

Лучший способ сделать это -

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

и для очистки

saleItemNew["1"] = new List<SaleItem>(); 
0 голосов
/ 19 июня 2009

Добавление списка в словарь - просто поверхностная копия ... Новый список с такими же значениями не создается и не добавляется (глубокая копия); скорее ссылка на старый список добавлена.

0 голосов
/ 19 июня 2009

это связано с использованием памяти и указателями. У вас есть стек и куча при выделении памяти для объектов, эта память - одна куча. Ваша переменная saleItems определена в стеке и указывает на адрес памяти в куче. Ваш словарь также находится в стеке, указывая на кучу.

когда вы говорите:

saleItems = new List<SaleItem>()

переменная saleItems помещается в стек и содержит адрес в памяти, указывающий на расположение данных в куче. Скажем 0x0100. Теперь вы добавляете новый DictionaryItem в свой словарь. DictionaryItem помещается в кучу с двумя свойствами: ключ и значение. В этом случае вы добавили 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-624484 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...