2012-01-20 3 views
1

У меня есть два словаря. Когда я изменяю значение в словаре 1, то такое же изменение появляется в словаре 2. Как изменить значение только в словаре 1, а не в словаре 2?Как скопировать список словарей

List<Dictionary<string, string>> ld1 = new List<Dictionary<string, string>>(); 
    Dictionary<string, string> d1 = new Dictionary<string,string>(); 

    d1.Add("Text", "Value1"); 
    d1.Add("Format", "Value2"); 
    ld1.Add(d1); 

    List<Dictionary<string, string>> ld2 = new List<Dictionary<string, string>>(ld1); 
    // ld2 = ld1 

    ld1[0]["Text"] = "Eulav";  // should: change only in the first dictionary 
            // actually: changes in the second dictionary as well 

    Console.WriteLine(ld1[0]["Text"]); 
    Console.WriteLine(ld2[0]["Text"]); 

Выходы

Eulav 
Eulav 

ответ

2

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

var ld2 = new List<Dictionary<string, string>>(); 

foreach (var dict in ld1) 
{ 
    ld2.Add(new Dictionary<string, string>(dict)); 
} 
+0

это работает, спасибо – Radicz

3

Если вы хотите иметь две неглубокие копии конкретного Dictionary<TKey, TValue> затем просто использовать конструктор для создания копии

Dictionary<string, string> ld1 = ...; 
Dictionary<string, string> ld2 = new Dictionary<string, string>(ld1); 

Примечание: В данном конкретном случае это будет глубокая копия, так как string неизменна и не имеет ребенка данных, которую нужно глубоко скопирована

+0

это работает, спасибо – Radicz

1

Важно помнить здесь является то, что если вы создаете два экземпляры (два разных распределения памяти) List, вы создаете только один экземпляр словаря.

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

Как вам предложили другие, здесь вам нужно создать еще один экземпляр Dictinary (выделенное выделение памяти) и скопировать ему значения первого.

Dictionary<string, string> ld2 = new Dictionary<string, string>(ld1); 

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

+0

это работает, спасибо – Radicz

1

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

Вы можете реализовать интерфейс IClonable. Я оставляю Лил пример:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Dictionary<int, Person> dic1 = new Dictionary<int, Person>(); 
     dic1.Add(0, new Person { Name = "user1158781" }); 
     Dictionary<int, Person> dic2 = new Dictionary<int, Person>(); 
     foreach (var item in dic1) 
     { 
      dic2.Add(item.Key, (Person)item.Value.Clone()); 
     } 

     dic1[0].Name = "gz"; 

     Console.WriteLine(dic1[0].Name); 
     Console.WriteLine(dic2[0].Name); 
    } 

    class Person : ICloneable 
    { 
     public string Name { get; set; } 

     public object Clone() 
     { 
      return new Person { Name = this.Name }; 
     } 
    } 
} 
Смежные вопросы