C#中以对象为字典键时ContainsKey无法识别已有键的问题
字典对象键无法被ContainsKey识别的问题
我使用以下代码检查字典tree中是否存在以parent对象为键的关系,若存在则更新其子节点数组,并为child对象添加空条目:
//Checking if there already exists a relationship if (tree.ContainsKey(parent)) { //get the current children temp = tree[parent]; //add the new child temp = temp.Append(child).ToArray(); //overwrite the current children tree[parent] = temp; //create new record with null children tree[child] = new Node[] { }; }
但调试时发现这段代码无法识别字典中已存在的内容相同但引用不同的对象键,附上两张对比截图:
- 字典中已存在的键:

- 待检查的键:

问题原因
.NET的Dictionary<TKey, TValue>默认使用引用相等性判断键是否相等。也就是说,只有当两个Node对象是内存中的同一个实例时,ContainsKey才会认为它们是同一个键。即使两个对象的属性(比如Id、Name)完全一致,只要是不同的实例,就会被判定为不同的键。
解决方法
要让字典基于对象内容判断键是否相等,有两种常用方案:
方案1:重写Node类的Equals和GetHashCode方法
在Node类中重写这两个方法,基于对象的核心属性(比如截图里的Id和Name)定义相等逻辑:
public class Node { public int Id { get; set; } public string Name { get; set; } // 重写Equals方法,基于属性判断相等 public override bool Equals(object obj) { if (obj is not Node otherNode) return false; return Id == otherNode.Id && Name == otherNode.Name; } // 重写GetHashCode,确保相等的对象返回相同哈希值 public override int GetHashCode() { return HashCode.Combine(Id, Name); } }
方案2:使用自定义的IEqualityComparer<Node>
如果无法修改Node类代码,可以创建自定义比较器,在初始化字典时传入:
// 自定义比较器类 public class NodeEqualityComparer : IEqualityComparer<Node> { public bool Equals(Node x, Node y) { if (x == null && y == null) return true; if (x == null || y == null) return false; return x.Id == y.Id && x.Name == y.Name; } public int GetHashCode(Node obj) { if (obj == null) return 0; return HashCode.Combine(obj.Id, obj.Name); } } // 创建字典时传入比较器 var tree = new Dictionary<Node, Node[]>(new NodeEqualityComparer());
内容的提问来源于stack exchange,提问作者Gerard Coleiro
相关产品推荐
相关产品推荐

