我目前正在尝试使用containskey方法来检查我所拥有的字典是否包含自定义类型的某个键。要做到这一点,我应该覆盖gethashcode函数,我有,但是containskey方法仍然不起作用。一定有什么地方我做得不对,但我还没有弄清楚在过去的5个小时里我一直在尝试这个:
public class Parameter : IEquatable<Parameter>
{
public string Field { get; set; }
public string Content { get; set; }
public bool Equals(Parameter other)
{
if (other == null)
{
return false;
}
return Field.Equals(other.Field) && Content.Equals(other.Content);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Field.GetHashCode();
hash = hash * 23 + Content.GetHashCode();
return hash;
}
}
}
public class Trigger : IEquatable<Trigger>
{
public Dictionary<int, Parameter> Parameters { get; private set; }
private string Event { get; set; }
public bool Equals(Trigger item)
{
if (item == null)
{
return false;
}
return Event.Equals(item.Event) && Parameters.Equals(item.Parameters);
}
public override int GetHashCode()
{
unchecked
{
var hash = 17;
hash = hash * 23 + Parameters.GetHashCode();
hash = hash * 23 + Event.GetHashCode();
return hash;
}
}
}
为额外的清晰度:我有一个字典(触发器,状态),我想检查的键,所以我假设,如果我确保我所有的子类是等价的,我可以使用containskey方法,但显然它没有。
编辑:我现在所做的是实现Jon Skeet的字典类,并使用它来做我的检查:
public override bool Equals(object o)
{
var item = o as Trigger;
if (item == null)
{
return false;
}
return Event.Equals(item.Event) && Dictionaries.Equals(Parameters, item.Parameters);
}
public override int GetHashCode()
{
var hash = 17;
hash = hash * 23 + Dictionaries.GetHashCode(Parameters);
hash = hash * 23 + Event.GetHashCode();
return hash;
}
Dictionary<,>
本身不覆盖Equals
和GetHashCode
-所以你的Trigger
实现被打破了。你需要计算出你想要的等式,并自己实现它。
我在protobuf-csharp-port中有一个示例实现,您可能想看看。
编辑:你的修改还是不太对。你应该像这样实现相等:return Event.Equals(item.Event) &&
Dictionaries.Equals(Parameters, item.Parameters);
并实现GetHashCode
为:
var hash = 17;
hash = hash * 23 + Dictionaries.GetHashCode(Parameters);
hash = hash * 23 + Event.GetHashCode();
return hash;
应该使用重载的构造函数:
Dictionary<TKey, TValue>(IDictionary<TKey, TValue>, IEqualityComparer<TKey>)
不使用autoproperty,使用备份字段