繁体   English   中英

对于值对象与实体,等于覆盖和==重载

[英]Equals override and == overload, for value objects vs entities

我发现了很多关于Equals重载和==运算符重载之间的区别的讨论,但是对于何时应该重载默认的相等行为似乎有些不满,这使我怀疑这样做的好方法。

以下是我的理解,如果您觉得有问题,请告诉我:

1)对于非不可变类型(为什么),不建议==重载,对于不可变类型(又名DDD的值对象),如果值相同而不是引用,则使==比较返回true很有用。

2)在不可变类型中也应覆盖等于(和GetHashCode),以对类型内相关字段的每个值进行良好的比较。

3)实体相等吗?

重写Equals并仅比较id属性是一个好主意吗? 还是应该让默认的对象行为比较参考?

对于这两个选项,我认为如果我遵循这样的规则,即在线程上下文中始终只具有一个特定实体的一个实例,则结果应该是相同的,但是其中一个选项存在某些缺点或优点。应该注意什么?

动机

我认为,正确的平等操作是面向对象世界中最被低估的工具之一。 是的,您应该在有意义的地方绝对实现它们,这将使您的程序更加简洁。

例如比较

Assert.Equal(expectedAddress.Street, address.Street);
Assert.Equal(expectedAddress.City, address.City);
Assert.Equal(expectedAddress.Zip, address.Zip);
Assert.Equal(expectedAddress.State, address.State);
Assert.Equal(expectedAddress.Country, address.Country);

Assert.Equal(expectedAddress, address);

当您具有深层嵌套的价值对象时,这变得更加极端。

何时使用

为了不产生尴尬的行为,仅对不可变类型实现相等操作。 这很重要,因为例如哈希映射在可变类型上将无法正确运行(请考虑当对象的哈希码在哈希图中时发生变化时会发生什么)。

对于某些可变类型,单独实现Equals可能有意义,但是通常不建议这样做,例如,通过Microsoft代码分析规则

价值对象

平等操作对价值对象最有用。 还重写相等运算符以使相等比较看起来自然。

相等操作的实现很简单:考虑所有数据字段,但忽略计算的属性。 这将创建纯粹基于内容的相等操作。

由于在值对象上实现相等操作是机制性的,因此有一个名为Equ会自动为您执行此操作(我自己写了)。 它将在静态实例化时间创建相等操作,这些操作具有与手动编写的EqualsGetHashCode实现相同的运行时性能。

实体

对于实体,它变得有些棘手。 问题在于, 从域的角度来看,通常通常并不清楚什么是平等。

显然,两个具有不同ID的Customer实体是不相等的。 就是这样。 具有相同ID但状态不同的两个Customer实体是否相等? 难题。

好消息是这种功能并不是真正需要的。 因此,我的建议是: 不要对实体实施相等操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM