簡體   English   中英

我是否正確實現了Equals()/ GetHashCode()?

[英]Have I implemented Equals()/GetHashCode() correctly?

該計划正在實施此實施:

class Instrument
{
    public string ClassCode { get; set; }
    public string Ticker { get; set; }
    public override string ToString()
    {
        return " ClassCode: " + ClassCode + " Ticker: " + Ticker + '.';
    }
}

但是因為我需要在Dictionary中使用Instrument,所以我決定實現equals / hashcode:

class Instrument
{
    public string ClassCode { get; set; }
    public string Ticker { get; set; }
    public override string ToString()
    {
        return " ClassCode: " + ClassCode + " Ticker: " + Ticker + '.';
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        Instrument instrument = obj as Instrument;
        if (instrument == null)
            return false;

        return ((ClassCode.Equals(instrument.ClassCode)) && (Ticker.Equals(instrument.Ticker));
    }

    public override int GetHashCode()
    {
        int hash = 13;
        hash = (hash * 7) + ClassCode.GetHashCode();
        hash = (hash * 7) + Ticker.GetHashCode();
        return hash;
    }
}

現在該程序已停止工作。 在這樣或類似的地方,我收到“KeyNotFoundException”:

if (cache.Keys.Any(instrument => instrument.Ticker == newTicker && instrument.ClassCode == newClassCode))

是否有可能某些代碼段假定equals和hashcode未實現? 或者我可能只是錯誤地實現了它們? 對不起,我不熟悉C#中的這些高級功能作為最后一段代碼,不知道它是如何與equals或hashCode連接的。

您的HashCode和Equals方法應僅依賴於不可變屬性 - 您的實現使用ClassCode和Ticker,它們都具有setter並因此是可變的。

首先 ,您可以使用ContainsKey而不是使用cache.Keys.Any

bool contains = cache.ContainsKey(
    new Instrument { Ticker = newTicker, ClassCode = newClassCode });

第一次遍歷整個鍵列表 - O(n),而第二次使用Dictionary的內置哈希表實現 - O(1)。

其次 ,檢查實現中的空引用:

public override bool Equals(object obj)
{
    if (obj == null)
        return false;

    Instrument instrument = obj as Instrument;
    if (instrument == null)
        return false;

    // 1. string.Equals can handle null references.
    // 2. object.ReferenceEquals for better preformances when it's the same object
    return (object.ReferenceEquals(this, instrument)) ||
        (string.Equals(ClassCode, instrument.ClassCode) &&
        string.Equals(Ticker, instrument.Ticker));
}

public override int GetHashCode()
{
    int hash = 13;
    if (ClassCode != null)
        hash = (hash * 7) + ClassCode.GetHashCode();
    if (Ticker!= null)
        hash = (hash * 7) + Ticker.GetHashCode();

    return hash;
}

除此之外,我看不出有問題。

但是因為我需要在Dictionary中使用Instrument,所以我決定實現equals / hashcode

這是錯誤的原因。 您的類已經具有Equality和GetHashCode的實現,這些實現適用,高效且經過測試可用於Dictionary。

我是否正確實現了Equals()/ GetHashCode()?

不,你錯過了==開頭的重載。 只有當您使儀器不可變時才會可靠。

您最好的行動方案是不要覆蓋任何這些成員。

另請參閱此MSDN建議 注意“平等的保證”和

不建議在非不可變類型中覆蓋operator ==。

暫無
暫無

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

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