我有以下课程
class Product : IEquatable<Product>
{
public Guid Id { get; set; }
public bool Equals(Product other)
{
return Id.Equals(other.Id);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试创建列表项的唯一列表,如下所示
Guid a = Guid.NewGuid();
List<Product> listA = new List<Product>();
listA.Add(new Product(){Id = a});
List<Product> listB = new List<Product>();
listB.Add(new Product()
{
Id = a
});
Debug.Assert(listA.Union(listB).Count()==1);
Run Code Online (Sandbox Code Playgroud)
返回两个项目,直到我覆盖object.Equals方法,一旦我这样做,我的代码如下
class Product : IEquatable<Product>
{
public Guid Id { get; set; }
public bool Equals(Product other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.Id.Equals(Id);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (Product)) return false;
return Equals((Product) obj);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
我的IEquatable Equals方法现在被调用,但是只有当我覆盖基本方法时,如果我在对象equals方法上放置一个断点,它永远不会被调用.
为什么是这样?
---- UPDATE
所以用产品类
class Product : IEquatable<Product>
{
public Guid Id
{
get;
set;
}
public bool Equals(Product other)
{
return Id.Equals(other.Id);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
如果删除了GetHashCode,那么Equals的IEquatable实现永远不会被击中我明白你应该一起实现Equals和GetHashCode,这是为什么?
问题出在原始实现中,您没有覆盖该GetHashcode方法.引擎盖下Union使用Set<T>样式结构来删除重复项.此结构根据返回的值将对象放入存储区GetHashCode.如果哈希码在相等的对象之间不匹配(它必须这样做)那么它们可能被放在不同的桶中并且从未与它们进行比较Equals
一般来说,如果你实施,IEquatable<T>你应该总是
Object.EqualsObject.GetHashCode不这样做会让你陷入这样的境地.
请注意,您的实现可能会有所简化
class Product : IEquatable<Product>
{
public Guid Id { get; set; }
public bool Equals(Product other)
{
if (ReferenceEquals(null, other)) {
return false;
}
return other.Id == this.Id;
}
public override bool Equals(object obj)
{
return Equals(obj as Product);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)