Implementing the IEquatable of T interface for object equality in a derived class with C# .NET
May 19, 2015 1 Comment
In this post we saw how to implement the IEquatable of T interface for a simple Person class. We based our equality logic on the Id property of the object. We implemented the IEquatable.Equals method and also overrode the Object.Equals and GetHashCode methods.
In this post we’ll see how you might go about extending that logic in derived classes. For that purpose we’ll go with another object:
public class Building { public double Area { get; set; } public int NumberOfRooms { get; set; } public string Address { get; set; } public bool ForSale { get; set; } public DateTime DateBuilt { get; set; } }
We’ll base our equality logic on the Address and NumberOfRooms field. Let’s implement the same methods and overrides as in the post referenced above:
public class Building : IEquatable<Building> { public double Area { get; set; } public int NumberOfRooms { get; set; } public string Address { get; set; } public bool ForSale { get; set; } public DateTime DateBuilt { get; set; } public bool Equals(Building other) { if (other == null) return false; return (Address == other.Address && NumberOfRooms == other.NumberOfRooms); } public override bool Equals(object obj) { if (obj == null) return false; if (obj is Building) { Building other = (Building)obj; return this.Equals(other); } return false; } public override int GetHashCode() { return (Address.GetHashCode() + NumberOfRooms); } }
Let’s check if it works:
static void Main(string[] args) { Building buildingOne = new Building() { Address = "London", Area = 123, DateBuilt = DateTime.UtcNow.AddYears(-2), ForSale = true, NumberOfRooms = 4 }; Building buildingTwo = new Building() { Address = "London", Area = 123, DateBuilt = DateTime.UtcNow.AddYears(-2), ForSale = true, NumberOfRooms = 4 }; Console.WriteLine(buildingOne.Equals(buildingTwo)); }
It will return true. If you change the address or number of rooms field in either instance then the code will print false on the console window.
Let’s have a derived class now:
public class Apartment : Building { public int Floor { get; set; } public int DoorNumber { get; set; } }
Let’s say that two apartments are equal if equality is satisfied for the base class and if the Floor and DoorNumber properties are the same. I.e. the Apartment object equality will be based on 4 properties in total. We still need to implement and override the same methods in the derived class but we can reuse the equality logic of the base class. Here’s a possible solution:
public class Apartment : Building, IEquatable<Apartment> { public int Floor { get; set; } public int DoorNumber { get; set; } public bool Equals(Apartment other) { if (!base.Equals(other)) return false; return (Floor == other.Floor && DoorNumber == other.DoorNumber); } public override bool Equals(object obj) { if (!base.Equals(obj)) return false; Apartment other = (Apartment)obj; return this.Equals(other); } public override int GetHashCode() { return base.GetHashCode() + Floor + DoorNumber; } }
Let’s see if it works:
Apartment apartmentOne = new Apartment() { Address = "London", Area = 123, DateBuilt = DateTime.UtcNow.AddYears(-2), ForSale = true, NumberOfRooms = 4, Floor = 2, DoorNumber = 3 }; Apartment apartmentTwo = new Apartment() { Address = "London", Area = 123, DateBuilt = DateTime.UtcNow.AddYears(-2), ForSale = true, NumberOfRooms = 4, Floor = 2, DoorNumber = 3 }; Console.WriteLine(apartmentOne.Equals(apartmentTwo));
It will indeed print true. As soon as you change any of the 4 key properties the console will print false.
View all various C# language feature related posts here.
Reblogged this on Dinesh Ram Kali..