简体   繁体   English

我是否正确实现了Equals()/ GetHashCode()?

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

The program was working with this implementation: 该计划正在实施此实施:

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

But because I need to use Instrument in Dictionary I've decided to implement equals/hashcode: 但是因为我需要在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;
    }
}

Now the program has stopped working. 现在该程序已停止工作。 In such or similar places I receive "KeyNotFoundException": 在这样或类似的地方,我收到“KeyNotFoundException”:

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

Is it possible that some pieces of the code assume that equals and hashcode IS NOT implemented? 是否有可能某些代码段假定equals和hashcode未实现? Or probably I just implemented them wrong? 或者我可能只是错误地实现了它们? Sorry I'm not familiar with such advanced features in C# as the last piece of code and don't know how it is connected with equals or hashCode. 对不起,我不熟悉C#中的这些高级功能作为最后一段代码,不知道它是如何与equals或hashCode连接的。

您的HashCode和Equals方法应仅依赖于不可变属性 - 您的实现使用ClassCode和Ticker,它们都具有setter并因此是可变的。

First , instead of using cache.Keys.Any you can just use ContainsKey . 首先 ,您可以使用ContainsKey而不是使用cache.Keys.Any

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

The first iterate over the whole keys list - O(n), while the second uses Dictionary's built in hash table implementation - O(1). 第一次遍历整个键列表 - O(n),而第二次使用Dictionary的内置哈希表实现 - O(1)。

Second , check for null reference in your implementation: 其次 ,检查实现中的空引用:

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;
}

Other than that, I can't see a problem. 除此之外,我看不出有问题。

But because I need to use Instrument in Dictionary I've decided to implement equals/hashcode 但是因为我需要在Dictionary中使用Instrument,所以我决定实现equals / hashcode

That's the wrong reason. 这是错误的原因。 Your class already has implementations for Equality and GetHashCode that are suitable, efficient and tested for use in a Dictionary. 您的类已经具有Equality和GetHashCode的实现,这些实现适用,高效且经过测试可用于Dictionary。

Have I implemented Equals()/GetHashCode() correctly? 我是否正确实现了Equals()/ GetHashCode()?

No. You are missing an overload for == to start with. 不,你错过了==开头的重载。 And it will only be reliable when you make Instrument immutable. 只有当您使仪器不可变时才会可靠。

Your best course of action is not to override any of those members. 您最好的行动方案是不要覆盖任何这些成员。

Also see this MSDN advice . 另请参阅此MSDN建议 Notice the "guarantees of Equals" and 注意“平等的保证”和

Overriding operator == in non-immutable types is not recommended. 不建议在非不可变类型中覆盖operator ==。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM