首页 > 解决方案 > 何时以及为何在 C# 中使用“ValueObject”基类(来自 Microsoft Docs)?

问题描述

我试图了解 C# 中 ValueObject 的用例、何时使用以及 ValueObject 的需求。我在文档中看到它可以在我们想要初始化对象然后不想更改意味着使其不可变的属性时使用,但它与单例模式不同,您可以在构造函数中初始化对象属性并且它会在应用程序的整个生命周期内持续存在吗?现在为什么我们需要 ValueObject 以及这个 EqualityComparer 和 hashCode() 等的全部内容。

来自 Microsoft Docs 的代码:

    public abstract class ValueObject
    {
        protected static bool EqualOperator(ValueObject left, ValueObject right)
        {
            if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null))
            {
                return false;
            }
            return ReferenceEquals(left, null) || left.Equals(right);
        }
    
        protected static bool NotEqualOperator(ValueObject left, ValueObject right)
        {
            return !(EqualOperator(left, right));
        }
    
        protected abstract IEnumerable<object> GetEqualityComponents();
    
        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != GetType())
            {
                return false;
            }
    
            var other = (ValueObject)obj;
    
            return this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
        }
    
        public override int GetHashCode()
        {
            return GetEqualityComponents()
                .Select(x => x != null ? x.GetHashCode() : 0)
                .Aggregate((x, y) => x ^ y);
        }
        // Other utility methods
    }

现在地址实体:

    public class Address : ValueObject
    {
        public String Street { get; private set; }
        public String City { get; private set; }
        public String State { get; private set; }
        public String Country { get; private set; }
        public String ZipCode { get; private set; }
    
        public Address() { }
    
        public Address(string street, string city, string state, string country, string zipcode)
        {
            Street = street;
            City = city;
            State = state;
            Country = country;
            ZipCode = zipcode;
        }
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            // Using a yield return statement to return each element one at a time
            yield return Street;
            yield return City;
            yield return State;
            yield return Country;
            yield return ZipCode;
        }
    }

在上面的代码中,这个地址是什么,我们为什么要使用ValueObject,这个equalOperator是什么,都写在ValueObject类中,只是想了解实时使用ValueObject的用例,为什么需要它,它是实时使用的关于使用 ValueObjects 的场景,以及为什么我们需要 Equality 运算符,而不是 valueObject 中的 equal 运算符。

我是这个话题的新手。

标签: c#value-objects

解决方案


ValueObject 与值对象或不可变对象不同。恕我直言, ValueObject当您使用类似领域驱动设计的方法时,该类应该用于业务逻辑。

在 DDD 中,值​​对象不能由 Id 标识,而是由对象中的字段标识,因此需要比较对象中的一个或多个属性的相等运算符。

这也是您无法更改属性的原因,因为该对象将无法与它的其他加载实例进行比较。就像在示例中一样,如果您更改门牌号,它就不再是同一个地址了。

在实现 DDD 值对象时,您必须将所有比较逻辑复制到每个类中,从而复制代码。

该类ValueObject消除了这种需求,并使您自己的对象更加以业务为中心(即更具可读性),就像在使用 DDD 时一样(或者只是一个干净的业务层)。


推荐阅读