[英]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. 只有当您使仪器不可变时才会可靠。
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.