Как скопировать список словарей - PullRequest
1 голос
/ 21 января 2012

У меня есть два словаря.Когда я изменяю значение в словаре 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

Ответы [ 4 ]

3 голосов
/ 21 января 2012

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

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

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

2 голосов
/ 21 января 2012

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

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

foreach (var dict in ld1)
{
    ld2.Add(new Dictionary<string, string>(dict));
}
1 голос
/ 21 января 2012

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

 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 };
        }
    }
}
1 голос
/ 21 января 2012

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

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

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

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

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

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