Метод Distinct
, скорее всего, будет использовать что-то похожее на HashSet<T>
внутри, что зависит от хеш-кода (очевидно).Вам также нужно переопределить GetHashCode
.
Мне кажется, у вас вообще есть ненужное дублирование.Оба ваших класса A
и B
используют в основном одну и ту же логику для определения равенства;что вы хотите, чтобы два Base
объекта были равны, если их идентификаторы равны и они одного типа?(Вот как это выглядит для меня; ваша реализация, кажется, содержит пару ошибок в этом случае, но это все еще мое лучшее предположение.)
Если это так, просто сделайте Base
внедрить IEquatable<Base>
иВаши реализации A
и B
становятся намного проще:
class Base : IEquatable<Base>
{
public Base(int id)
{
Id = id;
}
public int Id { get; private set; }
public bool Equals(Base other)
{
if (other == null)
{
return false;
}
// Ensure As only compare equal with other As
// and the same for Bs (and potentially other subtypes).
return other.GetType().Equals(GetType()) && other.Id == Id;
}
public override bool Equals(object other)
{
if (other is Base)
{
return Equals((Base)other);
}
return false;
}
public override int GetHashCode()
{
return Id;
}
}
class A : Base, I
{
public A(int id) : base(id)
{ }
public string Name
{
get { return this.Id + "-A"; }
}
}
class B : Base, I
{
public B(int id) : base(id)
{ }
public string Name
{
get { return this.Id + "-B"; }
}
}
Обратите внимание, что я также изменил установщик свойства Id
на private
;в общем, очень рискованная игра - сделать поле или свойство доступным для записи, когда оно используется в реализации GetHashCode
типа (поскольку, если хеш-код объекта когда-либо изменяется, он перестает работать как ключ в хеш-таблице).
Этот комментарий становится ненужным, если вы примените мою рекомендацию выше.
Также, предупреждение! Мне кажется, что вы рискуетебесконечной рекурсии в вашем B.Equals
методе:
public override bool Equals(object obj)
{
if (obj is A)
// There is no method with the signature Equals(A);
// so this will just call your Equals(object) method --
// i.e., THIS method -- over and over again.
return this.Equals(obj as A);
else
return object.ReferenceEquals(this, obj);
}