Пользовательский класс используется в качестве ключа в словаре, но ключ не найден

StackOverflow https://stackoverflow.com/questions/1632768

Вопрос

У меня есть класс, показанный ниже, который используется в качестве ключа в Dictionary<ValuesAandB, string> У меня возникают проблемы при попытке найти какой-либо ключ в этом словаре, он никогда не находит его вообще. Как видите, я переопределил Equals и GetHashCode.

Чтобы найти ключ, который я использую

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

Есть ли что-то еще, что я пропускаю? Кто-нибудь может указать, что я делаю не так?

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

И прежде чем кто-нибудь спросит, да, значения есть в словаре!

Это было полезно?

Решение

Как вы строите словарь? Вы передаете свой собственный компаратор равенства его конструктору?

Другие советы

Вы не переопределили Equals и GetHashCode. Вы реализовали второй класс, который может служить в качестве EqualityComparer. Если вы не создадите словарь с помощью EqualityComparer, он не будет использоваться.

Простейшим решением было бы переопределение GetHashCode и Equals напрямую, а не реализация компаратора (компараторы, как правило, интересны только в том случае, если вам нужно предоставить несколько различных типов сравнения (например, с учетом регистра и без учета регистра) или когда вам нужно иметь возможность выполнять сравнения в классе, который вы не контролируете.

Похоже, вы сравниваете две строки. Iirc, при использовании .Equals () вы сравниваете ссылку на строки, а не фактическое содержимое. Чтобы реализовать EqualityComparer, который работает со строками, вы должны использовать метод String.Compare ().

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
}

Я мог бы немного покончить с кодом, который должен вас закрыть ...

У меня была эта проблема, оказывается, словарь сравнивал ссылки для моего ключа, а не значения в объекте.

Я использовал пользовательский класс Point в качестве ключей. Я переопределил методы ToString () и GetHashCode () и альт, поиск ключей работал нормально.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top