c# - 何时以及为何在 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 运算符。
我是这个话题的新手。
解决方案
ValueObject 与值对象或不可变对象不同。恕我直言,
ValueObject
当您使用类似领域驱动设计的方法时,该类应该用于业务逻辑。
在 DDD 中,值对象不能由 Id 标识,而是由对象中的字段标识,因此需要比较对象中的一个或多个属性的相等运算符。
这也是您无法更改属性的原因,因为该对象将无法与它的其他加载实例进行比较。就像在示例中一样,如果您更改门牌号,它就不再是同一个地址了。
在实现 DDD 值对象时,您必须将所有比较逻辑复制到每个类中,从而复制代码。
该类ValueObject
消除了这种需求,并使您自己的对象更加以业务为中心(即更具可读性),就像在使用 DDD 时一样(或者只是一个干净的业务层)。
推荐阅读
- java - 旋转 HBox 中的每个 ImageView
- c# - 如何将命中点改为十字准线?
- c# - Automapper - 获取解析器中的所有条目
- git - 我在我的 CPanel 中找不到 Git 版本控制界面。非常需要它进行自动部署
- javascript - 如何使用 JavaScript/reactjs 检测 android 后点击?
- javascript - vue.js 组件在对另一个组件执行 vuex 操作后未更新
- python - 如何使用 pscp 将在 python 脚本中创建的文件复制到需要密码的远程服务器?
- c# - 无法从模型中引用 asp:HIddenField
- python - 如何比较 python/pandas 中 2 个 csv 文件(csv1 和 csv2)列中的所有条目?
- ag-grid - ag-grid angular上组标题的单击事件