CSharpFunctionalExtensions icon indicating copy to clipboard operation
CSharpFunctionalExtensions copied to clipboard

[Question] How to define equality for derived ValueObject

Open lonix1 opened this issue 4 years ago • 3 comments

I searched existing issues and the tests, but couldn't find how to do this.

A Person:

public class Person : ValueObject {

  public string Name { get; }
  public int Age { get; }

  public Person(string name, int age) {
    Name = name;
    Age = age;
  }

  protected override IEnumerable<object> GetEqualityComponents() {
    yield return Name;
    yield return Age;
  }
}

An Employee:

public class Employee : Person {

  public string Title { get; }

  public Employee(string name, int age, string title) : base(name, age) =>
    Title = title;

  protected override IEnumerable<object> GetEqualityComponents() {
    // ??? what goes here ???
  }
}

Does someone know what Employee.GetEqualityComponents() should contain?

I tried this:

yield return base.GetEqualityComponents();
yield return Title;

But my test fails:

public void Derived_VOs_should_be_equal() {
  var vo1 = new Employee("name", 100, "manager");
  var vo2 = new Employee("name", 100, "manager");
  vo1.Equals(vo2).Should().BeTrue();
  vo2.Equals(vo1).Should().BeTrue();
}

(I actually found a related test, but it was for the generic VO class.)

lonix1 avatar Jul 03 '21 13:07 lonix1

@lonix1 This should work:

public class Employee : Person {

  public string Title { get; }

  public Employee(string name, int age, string title) : base(name, age) =>
    Title = title;

  protected override IEnumerable<object> GetEqualityComponents() {
    yield return Title;
   foreach (var component in base.GetEqualityComponents())
   {
     yield return component;
   }
  }
}

Marking this issue as documentation to not forget to include in the future doc

vkhorikov avatar Jul 09 '21 15:07 vkhorikov

That's so obvious, I can't believe I didn't think about it - thanks so much!! :+1:

(Can we close this issue?)

lonix1 avatar Jul 14 '21 14:07 lonix1

No, let's keep it open, so that I don't forget to include this into documentation.

vkhorikov avatar Jul 14 '21 21:07 vkhorikov