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

该计划正在实施此实施:

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#中的这些高级function作为最后一段代码,不知道它是如何与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 ==。