我是否正确实现了 Equals()/GetHashCode() ?
该程序正在使用此实现:
class Instrument
{
public string ClassCode { get; set; }
public string Ticker { get; set; }
public override string ToString()
{
return " ClassCode: " + ClassCode + " Ticker: " + Ticker + '.';
}
}
但因为我需要在字典中使用 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联系起来的。
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:
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":
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?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的 HashCode 和 Equals 方法应该仅依赖于不可变属性 - 您的实现使用 ClassCode 和 Ticker,它们都具有 setter,因此是可变的。
Your HashCode and Equals methods should depend only on immutable properties - your implementation uses ClassCode and Ticker which both have setters and are therefore mutable.
首先,您可以使用包含Key。
第一个迭代整个键列表 - O(n),而第二个使用 Dictionary 的内置哈希表实现 - O(1)。
第二,检查您的实现中是否存在空引用:
除此之外,我看不出有什么问题。
First, instead of using
cache.Keys.Any
you can just use ContainsKey.The first iterate over the whole keys list - O(n), while the second uses Dictionary's built in hash table implementation - O(1).
Second, check for null reference in your implementation:
Other than that, I can't see a problem.
这是错误的原因。您的类已经具有 Equality 和 GetHashCode 的实现,它们适合、高效且经过测试可在字典中使用。
不。您缺少
==
的重载。只有当您使 Instrument 不可变时,它才会可靠。您最好的做法是不覆盖任何这些成员。
另请参阅此 MSDN 建议。注意“平等保证”和
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.
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. Notice the "guarantees of Equals" and