【发布时间】:2020-09-11 20:14:10
【问题描述】:
我正在尝试了解 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运算符。
我是这个话题的新手。
【问题讨论】:
-
这个“ValueObject”不是 C# 本身的一部分,也不是必需的。在使用过类似基本类型的代码(尽管使用了反射)之后,我可以从经验和意见的交集处保密地说,没有任何单独的观点:“不要这样做"。使用工具(ReSharper、最近的 VS?)或使用 TT 或类似工具提供的代码生成。
-
包含一个指向文档/代码源的链接,这样也可能提供它自己的基本原理。
-
就“为什么”而言,正如一些原始作者所设想的那样:它减少了代码重复,但代价是引入了人工子类型关系,因为具体类型只需要提供成员的值,通过 GetEqualityComponents 完成。使用具有自动代码生成/更新功能的工具时,这本身不是问题。
-
@VijenderReddyChintalapudi 我认为这个人在
Value Object上写得很好,并给出了一个真实世界使用示例的小想法。 - (enterprisecraftsmanship.com/posts/value-objects-explained) -
你不能只使用
records 来实现不变性吗?
标签: c# value-objects