Distinct () возвращает дубликаты с пользовательским типом

Я пытаюсь написать запрос Linq, который возвращает массив объектов с уникальными значениями в их конструкторах. Для целочисленных типов Distinct возвращает только одну копию каждого значения, но когда я пытаюсь создать свой список объектов, все разваливается. Я подозреваю, что это проблема с оператором равенства для моего класса, но когда я устанавливаю точку останова, она никогда не попадает.

Фильтрация повторяющегося int в подвыражении решает проблему, а также избавляет меня от создания объектов, которые будут следует немедленно отбросить, но мне любопытно, почему эта версия не работает.

ОБНОВЛЕНИЕ: 23:04 Некоторые люди указали, что MyType не отменяет GetHashCode (). Боюсь, я слишком упростил пример. Исходный MyType действительно его реализует. Я добавил его ниже, измененный только для того, чтобы поместить хеш-код во временную переменную перед его возвратом.

Пройдя через отладчик, я вижу, что все пять вызовов GetHashCode возвращают другое значение. А поскольку MyType наследуется только от Object, предположительно, это то же поведение, что и Object.

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

class Program
{
    static void Main(string[] args)
    {
        int[] list = { 1, 3, 4, 4, 5 };
        int[] list2 =
            (from value in list
             select value).Distinct().ToArray();    // One copy of each value.
        MyType[] distinct =
            (from value in list
             select new MyType(value)).Distinct().ToArray(); // Two objects created with 4.

        Array.ForEach(distinct, value => Console.WriteLine(value));
    }
}

class MyType
{
    public int Value { get; private set; }

    public MyType(int arg)
    {
        Value = arg;
    }

    public override int GetHashCode()
    {
        int retval = base.GetHashCode();
        return retval;
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        MyType rhs = obj as MyType;
        if ((Object)rhs == null)
            return false;

        return this == rhs;
    }

    public static bool operator ==(MyType lhs, MyType rhs)
    {
        bool result;

        if ((Object)lhs != null && (Object)rhs != null)
            result = lhs.Value == rhs.Value;
        else
            result = (Object)lhs == (Object)rhs;

        return result;
    }

    public static bool operator !=(MyType lhs, MyType rhs)
    {
        return !(lhs == rhs);
    }
}
7
задан ThatBlairGuy 30 November 2010 в 04:15
поделиться