Пересечение с 2 EntityCollections через пользовательский IEqualityComparer - PullRequest
1 голос
/ 24 января 2011

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

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, я добавлю необходимые операторы ifдля других моих типов, если я могу заставить это функционировать должным образом.Я знаю, что расширение Intersect использует GetHashCode вместо Equals для сравнения элементов, поэтому мне действительно все равно, что находится в моих equals, так как этот класс никогда не будет вызываться, кроме как для расширения Intersect в EntityCollections.Дело в том, что это не работает.В моем тестовом наборе я знаю, что у меня есть 28 элементов в моей исходной коллекции и 28 элементов в моей целевой папке, и все поля совпадают (очевидно, за исключением поля OtherId).Я прошел по коду GetHashCode, поскольку он зацикливался 56 раз, и смог сопоставить хэш-коды на всех 28 элементах каждого набора, но «пересечения» дали 0 отсчетов.Есть ли что-то, что я делаю неправильно или отсутствует?Благодарю.}

1 Ответ

1 голос
/ 24 января 2011

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

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

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

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

...