参照型の為,イコールで比較するとAreaIdの3と他のインスタンスのAreaIdの3は,異なるものと判断されます。
値として扱うなら,同じものと判定したいので,イコールメソッドのオーバーライドをします。これは次のValueObject抽象クラスを作成し,各ValueObjectでそれらを継承することで解消できます。
ValueObject抽象クラスの追加
ValueObjectsフォルダーにクラスを追加します。
クラスの名前は「ValueObject」とします。
ValueObjectのコーディング
作成したクラスに次のようにコーディングします。
namespace DDD.Domain.ValueObjects { public abstract class ValueObjectwhere T : ValueObject { public override bool Equals(object obj) { var vo = obj as T; if (vo == null) { return false; } return EqualsCore(vo); } public static bool operator ==(ValueObject vo1, ValueObject vo2) { return Equals(vo1, vo2); } public static bool operator !=(ValueObject vo1, ValueObject vo2) { return !Equals(vo1, vo2); } protected abstract bool EqualsCore(T other); public override string ToString() { return base.ToString(); } public override int GetHashCode() { return base.GetHashCode(); } } }
この抽象クラスの中で,Equalsと==の時に,参照型のクラスを値で比較する処理を入れているので,各ValueObjectは,この抽象クラスを継承し,EqualsCoreを実装することで,イコールの問題は解消されます。
AreaIdクラスで継承する
AreaIdクラスを次のように変更します。
namespace NDDD.Domain.ValueObjects { public sealed class AreaId : ValueObject { public AreaId(int value) { Value = value; } public int Value { get; } protected override bool EqualsCore(AreaId other) { return this.Value == other.Value; } } }
ValueObjectクラスを継承すると,EqualsCoreを実装するように強制されるので,その中で,クラスの比較ではなく,Valueというintの値で比較することで,イコールの問題は解消されます。 今後ValueObjectを作る時は,この抽象クラスを継承するという事を覚えておいてください。