比较在Dictionary中用作Key的对象

我的课:

public class myClass { public int A { get; set; } public int B { get; set; } public int C { get; set; } public int D { get; set; } } 

和主要的例子:

 Dictionary<myClass, List> dict = new Dictionary<myClass, List>(); myClass first = new myClass(); first.A = 2; first.B = 3; myClass second = new myClass(); second.A = 2; second.B = 3; second.C = 5; second.D = 6; dict.Add(first, new List()); if (dict.ContainsKey(second)) { // //should come here and update List for first (and only in this example) key // } else { // //if myFirst object has difference vlues of A or B properties // dict.Add(second, new List()); } 

这该怎么做?

如果您始终只希望字典在A和B上进行比较,则有两种选择。 使用实现IEqualityComparer 的构造函数并将比较逻辑放在那里,或者让你的类实现IEquateable GetHashCode和Equals,这样默认的比较器将为你提供你想要的结果。

如果您只想在一种情况下比较A和B,则需要使用.Keys比例和Linq扩展方法Contains ,它允许您传入IEqualityComparer 。 但是,当这样做时,你会失去使用Dictionary的速度优势,所以请谨慎使用它。

 public class MyClassSpecialComparer : IEqualityComparer { public bool Equals (myClass x, myClass y) { return xA == yA && xB == yB } public int GetHashCode(myClass x) { return xAGetHashCode() + xBGetHashCode(); } } //Special case for when you only want it to compare this one time //NOTE: This will be much slower than a normal lookup. var myClassSpecialComparer = new MyClassSpecialComparer(); Dictionary> dict = new Dictionary>(); //(Snip) if (dict.Keys.Contains(second, myClassSpecialComparer )) { // //should come here and update List for first (and only in this example) key // } //If you want it to always compare Dictionary> dict = new Dictionary>(new MyClassSpecialComparer()); 

默认情况下,比较会根据哈希代码将对象放入存储桶。 如果两个哈希码相同,则执行详细比较(通过调用Equals )。 如果您的类既不提供GetHashCode也不实现相等,则将使用默认的object.GetHashCode – 在这种情况下,您的类的任何特定内容都不会用于值比较语义。 只会找到相同的参考。 如果您不想这样做,请实现GetHashCode并实现相等性。

例如:

 public class myClass { public int A { get; set; } public int B { get; set; } public int C { get; set; } public int D { get; set; } public bool Equals(myClass other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return other.A == A && other.B == B && other.C == C && other.D == D; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != typeof (myClass)) return false; return Equals((myClass) obj); } public override int GetHashCode() { unchecked { int result = A; result = (result*397) ^ B; result = (result*397) ^ C; result = (result*397) ^ D; return result; } } } 

在myClass中覆盖:

  • GetHashCode方法

  • 等于方法

要实现GetHashCode方法,您只需从整数属性中XOR GetHashCodes即可。

(可选)覆盖ToString方法并实现IEquatable接口