2013-04-15 25 views
0

我目前正在尝试使用containskey方法来检查我所拥有的字典是否包含自定义类型的某个键。要做到这一点,我应该重写gethashcode函数,但是,containskey方法仍然无法正常工作。一定有什么东西我没有做正确的,但我还没有想通了,究竟是什么在过去的5小时里,我一直在尝试这样的:Contakeykey和gethashcode问题

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

为了增添清晰:我有一个字典(触发,状态),我想检查所以我假设如果我确保我所有的子类都可以equatable我可以只使用containskey方法,但显然它没有。

编辑:我现在做的是落实乔恩斯基特的字典类,并使用这个来做我的检查:

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

我没有看到自定义类型被用作代码中的键。你只使用int作为键。您需要显示问题的代码。 – Stewart

+0

我有一个字典<触发器,州>,我正在检查这个。状态是我有的另一个自定义类,但这对于这个问题并不重要 –

回答

4

Dictionary<,>本身并不覆盖EqualsGetHashCode - 所以你Trigger实现是破碎的。你需要弄清楚你想要什么样的平等并自己实现它。

我有一个sample implementation in 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; 
+0

我没有明白你的意思,我实现了自己的gethashcode覆盖,并且已经等于我的基础对象,所以我做错了什么? –

+0

@KendeJong:看看你的实现 - 你在调用'Parameters.Equals'和'Parameters.GetHashCode',并且这些*在Dictionary中没有被覆盖。 –

+0

所以,如果我理解正确,我应该实施覆盖“标准”字典的等于和gethashcodes? –

0

您应该使用重载的构造函数:

Dictionary<TKey, TValue>(IDictionary<TKey, TValue>, IEqualityComparer<TKey>) 

而不是使用autoproperty,使用备份领域。