首页 > 学院 > 开发设计 > 正文

C#:深入分析合并2个字典

2019-11-11 04:31:48
字体:
来源:转载
供稿:网友

合并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)。但是,如果运用不当,也会给我们带来一些不必要的麻烦,因为此时我们不想两个对象都改变,那么我们就得保证不要让两个对象引用相等,这样的话,才能做到只改变其一。


上一篇:google的gflag的使用

下一篇:几个小总结

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表