如何复制词典列表

时间:2012-01-20 23:45:37

标签: c# list dictionary copy duplicate-data

我有两本词典。当我更改字典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 个答案:

答案 0 :(得分:3)

如果您想拥有特定Dictionary<TKey, TValue>的两个浅表副本,那么只需使用构造函数创建副本

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

注意:在这种特殊情况下,它将是一个深层副本,因为string是不可变的,并且没有需要深度复制的子数据

答案 1 :(得分:2)

您只创建一个新列表,但该列表中的项目引用相同的对象(词典),因此您还需要创建每个项目的副本:

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

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

答案 2 :(得分:1)

这里需要记住的是,虽然您正在创建List的两个实例(两个不同的内存分配),但您只是创建了Dictionary的“一个”实例。

因此,两个列表都具有相同的内存指针,指向同一个字典。很明显,一个人的变化也会更新另一个人。

正如其他人所建议的,在这里你需要再创建一个Dictinary实例(一个不同的内存分配)并将第一个的值复制到它。

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

执行此操作会在列表中存储不同的实例,而其中一项更改不会影响其他实例。

答案 3 :(得分: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 };
        }
    }
}