Search code examples
c#equalscontainsgeneric-listiequatable

C# generic list of my class contains method not finding my instance


We have several classes in place for our CMS and I'm trying to get equality to work so I can check to see if a generic List contains an item. We have some layers of inheritance which I'll show you below. Below that, I'll show you some sample code that behaves contrary to my expectations. If you see something I've done wrong, please let me know. I've reduced the examples below just to show you the parts related. My actual classes are much bigger but I think this is everything you need to see.

IBaseTemplate.cs

public interface IBaseTemplate {
  bool Equals(IBaseTemplate other);
  string GUID { get; }
}

BasePage.cs

public class BasePage : System.Web.UI.Page, IBaseTemplate, IEquatable<IBaseTemplate> {

  // code to define properties, including GUID

  // various constructors
  public BasePage(string GUID) { 
    this.GUID = GUID;
  }

  // interface methods
  public bool Equals(IBaseTemplate other) {
    return (this.GUID == other.GUID);
  }

}

LandingPage.cs

public class LandingPage : BasePage {
  // a bunch of extra properties and method specific to LandingPage
  // but NO definition for Equals since that's taken care of in BasePage

  public LandingPage(string GUID) : base(GUID) {}
}

SamplePage.aspx.cs

var p1 = new LandingPage("{3473AEF9-7382-43E2-B783-DB9B88B825C5}");
var p2 = new LandingPage("{3473AEF9-7382-43E2-B783-DB9B88B825C5}");
var p3 = new LandingPage("{3473AEF9-7382-43E2-B783-DB9B88B825C5}");
var p4 = new LandingPage("{3473AEF9-7382-43E2-B783-DB9B88B825C5}");

var coll = new List<LandingPage>();
coll.Add(p1);
coll.Add(p2);
coll.Add(p3);

p1.Equals(p4);     // True, as expected
coll.Contains(p4); // False, but I expect True here!

I expect coll.Contains(p4) to return true because even though p1 through p4 are different instances, the inherited Equals method from BasePage compares their GUID properties as required by IBaseTemplate. Did I miss something here?

I looked at the docs for List(T)'s Contains method and I'm implementing IEquatable<T>.Equals where T is IBaseTemplate.


Solution

  • You need to override Object.Equals(Object) as well - see this link.