簡體   English   中英

當對象的標識符為空時,GetHashCode應該返回什么?

[英]What should GetHashCode return when object's identifier is null?

考慮到identity屬性可以為null,以下哪項是正確/更好的。

public override int GetHashCode()
{
    if (ID == null) {
        return base.GetHashCode();
    }
    return ID.GetHashCode();
}

要么

public override int GetHashCode()
{
    if (ID != null) {
        return ID.GetHashCode();
    }
     return 0;
}

更新1:更新了第二個選項。

更新2:以下是Equals實現:

public bool Equals(IContract other)
{
    if (other == null)
        return false;
    if (this.ID.Equals(other.ID)) {
        return true;
    }
    return false;
}

public override bool Equals(object obj)
{
    if (obj == null)
        return base.Equals(obj);
    if (!obj is IContract) {
        throw new InvalidCastException("The 'obj' argument is not an IContract object.");
    } else {
        return Equals((IContract)obj);
    }
}

ID是string類型。

它實際上取決於你想要的平等意義 - 重要的是兩個相等的對象返回相同的哈希碼。 當ID為空時,等式意味着什么? 目前,如果ID屬性具有相同的值,則Equals方法必須返回true ...但是如果ID為null,我們不知道它的作用。

如果你真的想要第一個版本的行為,我個人會使用:

return ID == null ? base.GetHashCode() : ID.GetHashCode();

編輯:基於你的Equals方法,看起來你可以制作你的GetHashCode方法:

return ID == null ? 0 : ID.GetHashCode();

請注意,您的Equals(IContract other)方法也可能如下所示:

return other != null && object.Equals(this.ID, other.ID);

如果this.ID為null,您當前的實現將實際拋出異常...

另外,你的Equals(object)方法是不正確的 - 如果你傳遞了一個不合適的對象類型,你不應該拋出異常,你應該只返回false ... ditto如果obj為null。 所以你實際上可以使用:

public override bool Equals(object obj)
{
    return Equals(obj as IContract);
}

但是,我關注基於接口的相等性。 通常,即使實現相同的接口,也不應認為兩類不同類型是相等的。

你可以簡單地return 0; ,你需要為相同的值返回相同的HashCode,而ID.GetHashCode()通常不會返回0,所以這樣的Hash函數可以滿足任何需求。 由於你沒有組合任何值(比如ID和Name Hashes),它非常清晰的ID是HashCode的定義源,因此Null ID的固定0聽起來合理。

否則,您對GetHashCode的整個方法覆蓋只考慮ID字段是錯誤的(並且您需要組合幾個字段來計算它們的哈希值)

在您編輯之后,我可以說第二個Equals覆蓋有太多代碼,只需將其替換為

public override bool Equals(object obj)
{
    return Equals(obj as Contract);
}

你的Equals(IContract合同)覆蓋對我來說是錯誤的,因為只有定義合同的東西是ID,如果IContract有更多的字段而不是ID,那么它將是一個糟糕的Equals覆蓋。

PS:實際上,如果IContract是一個接口,你可能需要將IEquatable<IContract>替換為具體的IEquatable<ClassName>合同,因為它將是一個糟糕的設計,能夠返回實現相同接口的不同類實例是相同的因果相等根據定義,需要在相等性檢查的第一階段檢查對象是否具有相同的類型(通常在99.9%的情況下)

也許你想要的是這樣的?

override int GetHashCode()
{
    if (ID != null)
        return ID.GetHashCode();

    return DBNull.Value.GetHashCode();
}

重要的是,如果兩個具有空ID的對象被認為是相等的嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM