合并2個字典,并不是一個難事,但是如果2個字典有鍵一樣,結果也許是正確的,但是卻意外改變了另一個對象,這并不是我們想看到的,在這里舉一個例子。
Dictionary<string,List<string>> dict1 = new Dictionary<string, List<string>>(); dict1.Add("qaz",new List<string>(){"100"}); dict1.Add("wsx",new List<string>(){"13"}); Dictionary<string, List<string>> dict2 = new Dictionary<string, List<string>>(); dict2.Add("qaz", new List<string>() { "11" }); dict2.Add("edc", new List<string>() { "17" }); //合并2個字典到dict Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();//創建dict foreach (var ele in dict1) //拿到dict1 { dict.Add(ele.Key,ele.Value); } foreach (var ele in dict2) //拿到dict2 { if(dict.ContainsKey(ele.Key)) dict[ele.Key].AddRange(ele.Value); else { dict.Add(ele.Key,ele.Value); } }dict的結果正確,{“qaz”, “100”和”11”}, {“wsx”,”13”},{“edc”,”17”} 但是dict1的結果怎么樣? 也被污染了!?。?dict1: {“qaz”, “100”和”11”}, {“wsx”,”13”}
正確的合并,不應該污染dict1
分析原因
dict首先添加了dict1的鍵值,也就是dict的鍵值都引用了dict1的鍵值; 接下來,再合并dict2時, 首先判斷dict中是否包含了dict2的鍵,如果包含,則直接再dict的鍵值中添加, 值又引用了同一個對象,也就是在dict1的鍵中添加了這個值。驗證下:
bool flag = object.ReferenceEquals(dict[ele.Key], dict1[ele.Key]);//結果是true所以污染了dict1
正確做法 避免dict[ele.Key]和dict1[ele.Key]引用相等?。?!
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>(); //先把鍵都合并到dict中,值都是新創建的 foreach (var key in dict1.Keys) { if (!dict.ContainsKey(key)) dict.Add(key, new List<string>()); } foreach (var key in dict2.Keys) { if (!dict.ContainsKey(key)) dict.Add(key, new List<string>()); } //分別將值添加進去 foreach (var ele in dict1) { dict[ele.Key].AddRange(ele.Value); } foreach (var ele in dict2) { dict[ele.Key].AddRange(ele.Value); }dict合并結果是正確的,并且dict1,dict2都未污染!
總結
合并字典帶來的,2個對象引用問題的思考
如果兩個對象都指向內存中同一個地址,也就是引用相等。此時,若改變其中一個對象,另一個也會改變! 利用這個引用相等,帶來了很多好處,比如函數間的引用傳值(by reference)。但是,如果運用不當,也會給我們帶來一些不必要的麻煩,因為此時我們不想兩個對象都改變,那么我們就得保證不要讓兩個對象引用相等,這樣的話,才能做到只改變其一。
新聞熱點
疑難解答