1

Не повторять этот вопрос слишком много, но я уже сделал поиск и подошел пустым по результату. Итак, у меня есть два EntityCollections типа T, и я хотел бы найти общие элементы в каждом. Уловка? Все поля, кроме одного, должны совпадать. Например, если тип T является типом CustomSet, а CustomSet включает в себя поля F1, F2, F3 и поле FK, то должны быть сопоставлены команды OtherId, F1, F2 и F3 (они могут быть строками, ints, что-либо действительно), а OtherId никогда не будет совпадение. Моя текущая реализация:Пересечь с 2 EntityCollections через пользовательский IEqualityComparer

var intersections = source.Intersect(destination).ToList(); 

никогда не дают никаких результатов, потому что OtherId колонна никогда не будет соответствовать в любой другой коллекции, даже если поля F1, F2 и F3 могут совпадать. Поэтому я предлагаю пользовательские реализации IEqualityComparer, которая выглядит следующим образом:

var intersections = source.Intersect(destination, new EntityCollectionComparer<T>()).ToList(); 

public class EntityCollectionComparer<T> : IEqualityComparer<T> 
{ 
    #region IEqualityComparer<T> Members 

    public bool Equals(T x, T y) 
    { 
     if (x.Equals(y)) 
      return true; 
     else 
      return false; 
    } 

    public int GetHashCode(T obj) 
    { 
     if (obj is CustomSet) 
     { 
      CustomSet temp = obj as CustomSet; 

      return (temp.F1.GetHashCode()^temp.F2.GetHashCode()^temp.F3.GetHashCode()); 
     } 
     return obj.GetHashCode(); 
    } 

Теперь, я только тестирование это так OBJ получения Передаваемого типа CustomSet, я добавлю необходимый если заявления для моих другие типы, если я могу заставить это функционировать должным образом. Я знаю, что расширение Intersect использует GetHashCode вместо Equals для сравнения элементов, поэтому мне действительно все равно, что на моих равных, поскольку этот класс никогда не будет вызван, а для расширения Intersect на EntityCollections. Дело в том, что это не работает. На моем тестовом наборе я знаю, что у меня есть 28 элементов в моей коллекции «source» и 28 элементов в моей коллекции «destination», и все поля соответствуют (очевидно, за исключением поля OtherId). Я прошел через код GetHashCode, когда он зациклился 56 раз и смог сопоставить хэш-коды по всем 28 пунктам из каждого набора, но «пересечения» дали 0 счет. Есть ли что-то, что я делаю неправильно или пропало? Благодарю. }

+0

Нет, Equals * будет * вызываться, но только для элементов, которые уже имеют совпадения по хэш-коду. Он не * просто * использует хэш-код. –

+0

Ahhh, Хорошо, позвольте мне попробовать, и я отчитаюсь. Благодарю. – dangerisgo

ответ

1

Это ваша проблема:

Я знаю, что расширение Intersect использует GetHashCode вместо Equals для сравнения элементов, поэтому я действительно не волнует, что в моих равных, как этот класс будет никогда не вызывается, а для расширения Intersect на EntityCollections.

Это просто неправда. GetHashCode используется как первый «быстрый» способ балансировки, но Equals по-прежнему будет вызываться для любых предметов с одинаковым хэшем, иначе вы не можете знать, что они равны.

Именно так работают хэш-таблицы и всегда работают: хеши должны отличаться для неравных значений, когда это возможно по соображениям производительности, но разрешено столкнуться.

+0

Спасибо! Это работает. – dangerisgo