我有一个这样的实体类(有很多东西失踪):Contains如何返回false,但GetHashCode()返回相同的数字,并且Equals返回true?
class Parent
{
private readonly Iesi.Collections.Generic.ISet<Child> children =
new Iesi.Collections.Generic.HashedSet<Child>();
public virtual void AddChild(Child child)
{
if (!this.children.Contains(child))
{
this.children.Add(child);
child.Parent = this;
}
}
public virtual void RemoveChild(Child child)
{
if (this.children.Contains(child))
{
child.Parent = null;
this.children.Remove(child);
}
}
}
然而,当我试图删除一个孩子,if
语句评估为false
。于是,我把对if
声明断点,评估某些表达式:
this.children.Contains(child) => false
this.children.ToList()[0].Equals(child) => true
this.children.ToList()[0].GetHashCode() => 1095838920
child.GetHashCode() => 1095838920
我的理解是,如果GetHashCode
返回相同的值,它会检查Equals
。为什么Contains
返回false?
我的两个Parent
和Child
实体从一个共同的Entity
基类,这是通用实体基类的非通用版本从3.0 NHibernate的食谱第25页继承。这里是我的基类:
public class Entity : IEntity
{
public virtual Guid Id { get; private set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity);
}
private static bool isTransient(Entity obj)
{
return obj != null &&
Equals(obj.Id, Guid.Empty);
}
private Type getUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity other)
{
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
if (!isTransient(this) &&
!isTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.getUnproxiedType();
var thisType = getUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
public override int GetHashCode()
{
if (Equals(Id, Guid.Empty))
return base.GetHashCode();
return Id.GetHashCode();
}
}
经过进一步调查,我觉得这样的事情正在发生:
- 调用
parent.AddChild(child)
- 保存到数据库中,这引起
child.Id
中产生 - 调用
parent.RemoveChild(child)
......并且如下面所讨论的那样,这改变了GetHashCode()
。
这是在我的程序中的错误的结果 - 我本来是要重装步骤2和步骤之间parent
3.
不过,我认为有更多的东西基本上是错误的。
出于好奇,你能不能用'私有Iesi.Collections.Generic.HashedSet儿童进行测试=新Iesi.Collections.Generic.HashedSet ();' –