Метод Contains не использует оператор ==
blockquote>Нет - он использует
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); } }
(Я не уверен в достоинствах неявное преобразование, кстати - я, как правило, держаться подальше от них.)