2012-01-20 57 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的實例(兩種不同的內存分配),你只創建Dictionary的「一個」實例。

因此,兩個列表都有相同的內存指針,指向同一個字典。很明顯,一個人的變化也會更新另一個人。

正如其他人所建議的,在這裏您需要創建一個額外的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 }; 
     } 
    } 
}