I am writing this question in the context of a DDD application. I found this code online on a number of blogs etc e.g. here: https://github.com/vkhorikov/DddInAction/blob/master/DddInPractice.Logic/Common/ValueObject.cs and here: https://lostechies.com/jimmybogard/2007/06/25/generic-value-object-equality/:
public abstract class ValueObject<T> where T : ValueObject<T> { protected abstract IEnumerable<object> GetEqualityComponents(); public override bool Equals(object obj) { var valueObject = obj as T; if (ReferenceEquals(valueObject, null)) return false; return EqualsCore(valueObject); } private bool EqualsCore(ValueObject<T> other) { return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents()); } public override int GetHashCode() { return GetEqualityComponents() .Aggregate(1, (current, obj) => current * 23 + (obj?.GetHashCode() ?? 0)); } public static bool operator ==(ValueObject<T> a, ValueObject<T> b) { if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) return true; if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false; return a.Equals(b); } public static bool operator !=(ValueObject<T> a, ValueObject<T> b) { return !(a == b); } } }
Every Value Object in my application inherits from it. It means the methods like: Equals and GetHashCode are dealt with implicitly. The main problem I see arises if I want to add a collection e.g. array as a member of a Value Object – in this scenario the generic value object .equals will not behave as expected as it cannot deal with collections. Therefore:
1) Can this class be tweaked to deal with collections? 2) Are there any other downfalls with this approach? 3) Is it advisable not to use a generic value class when developing a DDD application?