1

文档中有一段话NHibernate

注意:如果你定义了一个ISet复合元素,那么正确的实现Equals()和实现是非常重要的GetHashCode()

那里是什么correctly意思?是否有必要为域中的所有值对象实现这些方法?

扩展我的问题

Marc附加的用户Albic的文章中说:

实际上很难GetHashCode()正确实现,因为除了 Marc 已经提到的规则之外,哈希码在对象的生命周期内不应该改变。因此,用于计算哈希码的字段必须是不可变的。

当我使用NHibernate. 我的方法是根据对象的 ID 计算哈希码。ID 只能通过构造函数设置,因此如果您想更改 ID(这不太可能),您必须创建一个具有新 ID 的新对象,因此需要一个新的哈希码。这种方法最适用于 GUID,因为您可以提供随机生成 ID 的无参数构造函数。

我突然意识到我在AbstractEntity课堂上得到了什么:

public abstract class AbstractEntity<T> where T : AbstractEntity<T> {
    private Nullable<Int32> hashCode;
    
    public virtual Guid Id { get; protected set; }
    public virtual Byte[] Version { get; set; }

    public override Boolean Equals(Object obj) {
        var other = obj as T;
        if(other == null) {
            return false;
        }

        var thisIsNew = Equals(this.Id, Guid.Empty);
        var otherIsNew = Equals(other.Id, Guid.Empty);

        if(thisIsNew && otherIsNew) {
            return ReferenceEquals(this, other);
        }

        return this.Id.Equals(other.Id);
    } // public override Boolean Equals(Object obj) {

    public override Int32 GetHashCode() {
        if(this.hashCode.HasValue) {
            return this.hashCode.Value;
        }

        var thisIsNew = Equals(this.Id, Guid.Empty);
        if(thisIsNew) {
            this.hashCode = base.GetHashCode();
            return this.hashCode.Value;
        }
        return this.Id.GetHashCode();
    } // public override Int32 GetHashCode() {
    
    public static Boolean operator ==(AbstractEntity<T> l, AbstractEntity<T> r) {
        return Equals(l, r);
    }
    public static Boolean operator !=(AbstractEntity<T> l, AbstractEntity<T> r) {
        return !Equals(l, r);
    }
} // public abstract class AbstractEntity<T>...

由于所有components内容都嵌套在其中,因此我应该为它们entities实施Equals()和实施吗?GetHashCode()

4

2 回答 2

1

正确意味着为预期相等GetHashCode的实体返回相同的哈希码。因为两个实体的相等性是通过比较该代码来实现的。

另一方面,这意味着对于不相等的实体,必须尽可能保证哈希码的唯一性。

于 2013-04-11T11:03:21.900 回答
1

EqualsGetHashCode的文档很好地解释了这一点,并包含有关值对象实现的具体指导。对于值对象,如果对象类型相同且公共和私有字段相等,则 Equals 为真。但是,这种解释适用于框架值类型,您可以通过覆盖它来自由创建自己的 Equals。

GetHashCode 有两个必须遵守的规则:

  • 如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。但是,如果两个对象比较不相等,则两个对象的 GetHashCode 方法不必返回不同的值。

  • 只要确定对象的 Equals 方法的返回值的对象状态没有修改,对象的 GetHashCode 方法就必须始终返回相同的哈希码。请注意,这仅适用于应用程序的当前执行,并且如果再次运行应用程序,则可以返回不同的哈希码。

于 2013-04-11T14:39:45.977 回答