Правило перезаписи Wordpress удаляет дубликаты

Метод Contains не использует оператор ==

Нет - он использует Equals, который вы не переопределили ... так что вы получаете поведение по умолчанию Equals, которое должно проверять вместо ссылочного идентификатора. Вы должны переопределить Equals(object) и GetHashCode, чтобы они были согласованы друг с другом - и для здравого смысла, в соответствии с вашей перегрузкой ==.

Я также рекомендовал бы реализовать IEquatable<Element>, который List<Element> будет использовать предпочтение Equals(object), так как EqualityComparer<T>.Default подбирает его соответствующим образом.

О, и ваши перегрузки оператора должны обрабатывать и нулевые ссылки.

Я бы также сильно рекомендуют использовать частные поля вместо общедоступных и сделать ваш тип неизменным - запечатать его и сделать id только для чтения. Реализация равенства для изменяемых типов может привести к возникновению нечетных ситуаций. Например:

Dictionary<Element, string> dictionary = new Dictionary<Element, string>();
Element x = new Element(10);
dictionary[x] = "foo";
x.id = 100;
Console.WriteLine(dictionary[x]); // No such element!

Это произойдет потому, что хэш-код будет меняться (по крайней мере, в большинстве реализаций), поэтому хеш-таблица, лежащая в основе словаря, не сможет найти даже ссылку на тот же самый объект, который уже там.

Итак, ваш класс будет выглядеть примерно так:

internal sealed class Element : IEquatable<Element>
{
    private readonly int id;

    public int Id { get { return id; } }

    public Element(int id)
    {
        this.id = id;
    }

    public static implicit operator Element(int d)  
    {
        return new Element(d);
    }

    public static bool operator ==(Element e1, Element e2)
    {
        if (object.ReferenceEquals(e1, e2))
        {
            return true; 
        }
        if (object.ReferenceEquals(e1, null) ||
            object.ReferenceEquals(e2, null))
        {
            return false; 
        }
        return e1.id == e2.id;
    }

    public static bool operator !=(Element e1, Element e2)
    {
        // Delegate...
        return !(e1 == e2);
    }

    public bool Equals(Element other)
    {
        return this == other;
    }

    public override int GetHashCode()
    {
        return id;
    }

    public override bool Equals(object obj)
    {
        // Delegate...
        return Equals(obj as Element);
    }
}

(Я не уверен в достоинствах неявное преобразование, кстати - я, как правило, держаться подальше от них.)

0
задан yomisimie 13 July 2018 в 14:36
поделиться