Custom Class used as key in Dictionary but key not

2020-02-12 04:14发布

问题:

I have a class, show below, which is used as a key in a Dictionary<ValuesAandB, string> I'm having issues when trying to find any key within this dictionary, it never finds it at all. As you can see, I have overridden Equals and GetHashCode.

To look for the key I'm using

ValuesAandB key = new ValuesAandB(A,B);
if (DictionaryName.ContainsKey(key)) {
   ...
}

Is there anything else that I'm missing? Can anyone point out what I'm doing wrong?

private class ValuesAandB {
   public string valueA;
   public string valueB;

   // Constructor
   public ValuesAandB (string valueAIn, string valueBIn) {
     valueA = valueAIn;
     valueB = ValueBIn;
   }

   public class EqualityComparer : IEqualityComparer<ValuesAandB> {
      public bool Equals(ValuesAandB x, ValuesAandB y) {
         return ((x.valueA.Equals(y.valueA)) && (x.valueB.Equals(y.valueB)));
      }
      public int GetHashCode(ValuesAandB x) {
         return x.valueA.GetHashCode() ^ x.valueB.GetHashCode();
      }
   }
}

And before anyone asks, yes the values are in the Dictionary!

回答1:

How are you constructing the dictionary? Are you passing your custom equality comparer in to its constructor?



回答2:

You have not overridden Equals and GetHashCode. You have implemented a second class which can serve as an EqualityComparer. If you don't construct the Dictionary with the EqualityComparer, it will not be used.

The simplest fix would be to override GetHashCode and Equals directly rather than implementing a comparer (comparers are generally only interesting when you need to supply multiple different comparison types (case sensitive and case insensitive for example) or when you need to be able to perform comparisons on a class which you don't control.



回答3:

I had this problem, turns out the dictionary was comparing referances for my key, not the values in the object.

I was using a custom Point class as keys. I overrode the ToString() and the GetHashCode() methods and viola, key lookup worked fine.



回答4:

It looks like you're comparing two strings. Iirc, when using .Equals(), you are comparing the reference of the strings, not the actual contents. To implement an EqualityComparer that works with strings, you would want to use the String.Compare() method.

public class EqualityComparer : IEqualityComparer<ValuesAandB>
{
     public bool Equals(ValuesAandB x, ValuesAandB y)
     {
          return ((String.Compare(x.valueA,y.valueA) == 0) &&
            (String.Compare(x.valueB, y.valueB) == 0));
     }
     // gethashcode stuff here
}

I could be a little off with the code, that should get you close...