2013-07-03 3 views
1

Я четыре словаря, два являются (словарь в Словаре), объявление показано нижеКак сделать глубокую копию словаря в словаре в C#?

Dictionary<string, Dictionary<string, string>> dict_set = new Dictionary<string, Dictionary<string, string>>(); 
    Dictionary<string, Dictionary<string, string>> dict_Reset = new Dictionary<string, Dictionary<string, string>>(); 
    Dictionary<string, string> set_value = new Dictionary<string, string>(); 
    Dictionary<string, string> Reset_value = new Dictionary<string, string>(); 

Я хочу первым добавить элементы в словаре set_vlaue и Reset_value. после добавления значений, я добавляю эти словари к другим двум словарям, как показано ниже.

dict_set.Add(condiName, set_value); 
dict_Reset.Add(condiName, Reset_value); 
set_value.Clear(); 
Reset_value.Clear(); 

значение становится добавлено, но после добавления set_value и reset_value словарей, я хочу, чтобы очистить эти два словаря set_value и reset_value, но возникает проблема, что когда set_value и reset_value очищаются данные из dict_set и dict_reset также очищается ..

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

+3

См. Ответ Джона Скита здесь http://stackoverflow.com/questions/139592/what-is-the-best-way-to-clone-deep-copy-a-net-generic-dictionarystring-t – keyboardP

+0

@keyboardP на самом деле я хочу сделать глубокую копию словаря при выполнении ниже операции. dict_set.Add (condiName, set_value); dict_Reset.Add (condiName, Reset_value); один из них сделан, я хочу очистить set_value и reset_value .. чтобы новые значения могли быть добавлены. Но согласно вашему коду, если я делаю клонирование перед добавлением, один ключ будет иметь другие данные ключа. – Deadlock

+0

@KeyboardP: одна проблема с ответом Скита заключается в том, что он выполняет копию «Clone» листьев, которая не гарантирует глубокое копирование. Автор здесь хочет глубокого, так что это не так точный дубликат. Все еще с ответом Скита, легко приклеить решение. – quetzalcoatl

ответ

5

Я не знаю, что вы пытаетесь сделать в рабочем процессе, но почему бы не reinstancing вместо очистки?

dict_set.Clear(); 

к:

dict_set = new Dictionary<string, string>(); 
+0

Фактически set_value и reset_value dictionay хранят значения temp внутри цикла, когда все задание завершено, я хочу очистить их, чтобы на следующей итерации они будут иметь свежие значения. – Deadlock

+0

Если вы правильно поняли, вы хотите скопировать значения из set_/reset_value в словари dict_set/_reset, чем очистить словари set_/reset_value. SO: не используйте «set_/reset_value.Clear()» в вашем цикле, используйте «set_/reset_value = new ...» – mcj0in

+0

. Btw: вы можете изменить свое добавление от dict_set.Add (condiName, set_value); dict_Reset.Add (condiName, Reset_value); - dict_set.Add (condiName, новый словарь <строка, строка> (set_value)); dict_Reset.Add (condiName, новый словарь <строка, строка> (Reset_value)); – mcj0in

1

Помимо того, что тарелочки написали в ответ указал keyboardP, в большинстве управляемых языков вы можете очень легко выполнить глубокое копирование с помощью:

  • сериализации вещь
  • десериализация ее обратно

При десериализации вы, как правило, имеете полный глубокий клон оригинала. Сериализатор, как правило, выполняет все проверки идентификатора, прерывания циклов, дедупликацию и т. Д. В вашем случае это необязательно, но это может пригодиться позже.

Вы можете сериализовать его в XML, BinaryForm, JSON или как угодно и иметь под рукой. Это не так важно.

Теперь вернемся к вашему вопросу:

Это ваш код, просто укоротить немного:

var dict_set = new Dictionary<string, Dictionary<string, string>>(); 
var dict_Reset = new Dictionary<string, Dictionary<string, string>>(); 
var set_value = new Dictionary<string, string>(); 
var Reset_value = new Dictionary<string, string>(); 

dict_set.Add(condiName, set_value); 
dict_Reset.Add(condiName, Reset_value); 

set_value.Clear(); 
Reset_value.Clear(); 

Вы утверждаете, что:

(...), но проблема происходит, когда значения set_value и reset_value очищаются, данные из dict_set и dict_reset также очищаются.

Это Не верно. С этим кодом выше, невозможно. set/reset/dict_set/dict_reset - 4 различных объекта. Вызов «Очистить» на «set/reset» не может привести к удалению остальных.

Посмотрите на свой код. Ошибка в другом месте. Не здесь. Что-то другое очищает эти словари.

+0

после очистки set_value.Clear(); Reset_value.Clear(); данные, которые, как предполагалось, были в dict_set и dict_reset, отсутствуют. Только содержимое присутствует, это keyname, то есть condiname, на самом деле dict_set и dict_reset являются словарями в dicitionary. – Deadlock

0

Создав новый экземпляр, вы решите проблему выше.если кто-нибудь сталкивался с каким-либо другим лучшим решением, пожалуйста, сообщение ..

 dict_set.Add(condiName, new Dictionary<string, string>(set_value)); 
    dict_Reset.Add(condiName, new Dictionary<string, string>(Reset_value)); 
    set_value.Clear(); 
    Reset_value.Clear(); 
0

Я думаю, таким образом, внутренние словари в dict_set и dict_Reset не будут очищено

dict_set.Add(condiName, set_value.ToDictionary(entry => entry.Key,entry => entry.Value)); 
dict_Reset.Add(condiName, Reset_value.ToDictionary(entry => entry.Key,entry => entry.Value)); 
set_value.Clear(); 
Reset_value.Clear(); 

С помощью метода ToDictionary(), вы на самом деле создайте новый объект Dictionary, а не используйте ссылку на оригиналы оригиналов туров, чтобы вы могли спокойно их очистить. Добавление и удаление данных в set_value и Reset_value alsdo ​​не влияет на словари внутри dict_set и dict_Reset

Просто из любопытства, почему Reset_value с большой буквы и set_value нет?

+0

ok вы скопируете снова вставьте код с помощью set_value и dict_set в капитал. . :) – Deadlock