检查与对象的HashSet的相等性

我试图比较Definition类型的两个哈希集作为EqualityComparer.Default.Equals(value, oldValue)Definition定义如下

 public class Definition { public string Variable { get; set; } public HashSet LocationList { get; set; } public override bool Equals(object obj) { Definition other = obj as Definition; return other.Variable.Equals(this.Variable) && other.LocationList!= null &&this.LocationList != null && other.LocationList.Count == this.LocationList.Count && other.LocationList == this.LocationList; } public override int GetHashCode() { return this.Variable.GetHashCode() ^ this.LocationList.Count.GetHashCode();// ^ this.LocationList.GetHashCode(); } } public class Location { public int Line { get; set; } public int Column { get; set; } public int Position { get; set; } public string CodeTab { get; set; } public Location(int line, int col, int pos, string tab) { Line = line; Column = col; Position = pos; CodeTab = tab; } public override bool Equals(object obj) { Location other = obj as Location; return this.CodeTab == other.CodeTab && this.Position == other.Position && this.Column == other.Column && this.Line == other.Line; } public override int GetHashCode() { return this.CodeTab.GetHashCode() ^ this.Position.GetHashCode() ^ this.Column.GetHashCode() ^ this.Line.GetHashCode(); } } 

不知何故,对于类似的集合,尽管所有信息保持不变,但结果仍返回为false 。 唯一的区别是某些元素的位置是互换的,但我知道HashSet在比较时不会保留或检查顺序。 任何人都可以告诉我这里出了什么问题吗?

PS:我试过取消注释this.LocationList.GetHashCode() ,但是没有用。

您需要为集合创建比较器:

 var setComparer = HashSet.CreateSetComparer(); return other.Variable.Equals(this.Variable) && setComparer.Equals(this.LocationList, other.LocationList); 

EqualityComparer.Default将查找实现IEquatable的对象。 否则,它将推迟到ObjectEqualityComparerObjectEqualityComparer检查引用相等性。 这就是比较引用时看到错误的原因。

你真正想要做的是显式实现IEquatable 。 请注意,您应该使您的属性不可变,以使其正常工作:

 public class Location : IEquatable { public Location(int line, int col, int pos, string tab) { Line = line; Column = col; Position = pos; CodeTab = tab; } public int Line { get; private set; } public int Column { get; private set; } public int Position { get; private set; } public string CodeTab { get; private set; } public bool Equals(Location other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(CodeTab, other.CodeTab) && Column == other.Column && Line == other.Line && Position == other.Position; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((Location) obj); } public static bool operator ==(Location left, Location right) { return Equals(left, right); } public static bool operator !=(Location left, Location right) { return !Equals(left, right); } public override int GetHashCode() { unchecked { var hashCode = (CodeTab != null ? CodeTab.GetHashCode() : 0); hashCode = (hashCode*397) ^ Column; hashCode = (hashCode*397) ^ Line; hashCode = (hashCode*397) ^ Position; return hashCode; } } } 

现在,如果您查看Default创建的EqualityComparer类型,您将看到GenericEqualityComparer

 Console.WriteLine(EqualityComparer.Default.GetType())