Comparing lists of derived objects in C#

Viewed 252

I am new to C#. So please bear with me. I ran into a problem when I tried to compare two lists of different derived objects. I have a base class and a child class that inherits from it. The derived class has additional properties in the Equals() value comparison. I implement the IEquatable<> interface in the bass class as well as the derived class. I then fill two lists, each with one object from the derived class. The problem is when I call the Equals() function, it is the Base.Equals() that gets called. So basically the items in the list are treated as base class objects instead of the derived objects. How do I get out of this? See below code:

public class Base : IEquatable<Base>
{
    ... 
    public int BaseProperty {get; set;}
    ...
    public virtual bool Equals(Base other)
   {
      ...
      return this.BaseProperty == other.BaseProperty;
   }
}

public class Derived : Base, IEquatable<Derived>
{
   public int DerivedProperty {get; set:}
   ...
   
}

public class myList : IList<Base>, IEquatable<myList>
{
   private List<Base> _list;
   ...

   public bool Equals(myList other)
   {
      ...
      return ENumerable.SequenceEqual(this._list.OrderBy(r => r), other._list.OrderBy(r = > r));
   }
}

Main()
{
    Derived first = new Derived() {...};
    Derived second = new Derived() {...};
    myList<Derived> list1 = new List<Derived>(){ first };
    myList<Derived> list2 = new List<Derived>(){ second };

    bool ret = list1.Equals(list2);
}

The comparison of the two lists is done using SequenceEqual. When I stepped into the calls, I could see the trace ended up in Base.Equals(Base other) instead of Derived.Equals(Derived other). I can't cast it because in reality I have multiple derived classes and the lists could potentially hold any numbers of any objects. So my question is is there a way to make C# respect the derived type(s) in this situation? Thanks.

1 Answers

To try and answer your ultimate question -

So my question is is there a way to make C# respect the derived type(s) in this situation? Thanks.

The reason that the Base.Equals method (rather than the Derived.Equals method) is called is because of your declaration of 'myList' actually defines the Base class -

public class myList : IList<Base>, IEquatable<myList>

Instead, if you implement the myList in a generic way, then there will be no implicit conversion to Base when creating a myList object using the Derived class -

public class myListGeneric<T> : IList<T>, IEquatable<myListGeneric<T>> where T : class

I have tried as best as I can to implement an example for you on the following link (albeit inheriting from generics rather than their interfaces) to try and show you it working. It does differ slightly from what you have above, but it hopefully answers the question.

https://dotnetfiddle.net/VhWTCq

Hope that helps - copy it, step through, and have a go.

Related