简体   繁体   English

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

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

I found many discussions about the differences between Equals overriding and == operator overloading, but there seems to be some desagrement about when we should or not override the default equality behavior and that makes me doubt about the good way to do it. 我发现了很多关于Equals重载和==运算符重载之间的区别的讨论,但是对于何时应该重载默认的相等行为似乎有些不满,这使我怀疑这样做的好方法。

Below are my understandings, please tell me if something seems wrong to you: 以下是我的理解,如果您觉得有问题,请告诉我:

1) == overloading is not recommanded for non-immutable types (why ??), and is useful for immutable types (aka DDD's value objects) to make == comparaison return true if the values are the same but not the references. 1)对于非不可变类型(为什么),不建议==重载,对于不可变类型(又名DDD的值对象),如果值相同而不是引用,则使==比较返回true很有用。

2) Equals (and GetHashCode) should also be overriden in immutable types to perform good comparaison of each value of the relevant fields inside the type. 2)在不可变类型中也应覆盖等于(和GetHashCode),以对类型内相关字段的每个值进行良好的比较。

3) How about Equals for Entities ? 3)实体相等吗?

Is it a good idea to override Equals and only compare the id properties ? 重写Equals并仅比较id属性是一个好主意吗? Or should I let the default object behavior of comparing the references ? 还是应该让默认的对象行为比较参考?

For both of these options, I think if I follow the rule that I should always have only one instance of a particular entity in a thread context, the result should be the same, but is there some drawback or advantage of one of these options I should be aware of ? 对于这两个选项,我认为如果我遵循这样的规则,即在线程上下文中始终只具有一个特定实体的一个实例,则结果应该是相同的,但是其中一个选项存在某些缺点或优点。应该注意什么?

Motivation 动机

Proper equality operations are among the most underestimated tools in the object-oriented world in my opinion. 我认为,正确的平等操作是面向对象世界中最被低估的工具之一。 Yes, you should absolutely implement them where it makes sense, it will make your program a lot more concise. 是的,您应该在有意义的地方绝对实现它们,这将使您的程序更加简洁。

Eg compare 例如比较

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);

with

Assert.Equal(expectedAddress, address);

This becomes even more extreme when you have deeply nested value objects. 当您具有深层嵌套的价值对象时,这变得更加极端。

When to use 何时使用

To not produce awkward behavior, only implement equality operations on immutable types. 为了不产生尴尬的行为,仅对不可变类型实现相等操作。 This is important, because eg hash maps will not function correctly with mutable types (think about what happens when an object's hash code changes while it is in a hash map). 这很重要,因为例如哈希映射在可变类型上将无法正确运行(请考虑当对象的哈希码在哈希图中时发生变化时会发生什么)。

Implementing Equals alone could make sense for some mutable types, but is generally discouraged, eg by a Microsoft code analysis rule . 对于某些可变类型,单独实现Equals可能有意义,但是通常不建议这样做,例如,通过Microsoft代码分析规则

Value Objects 价值对象

Equality operations are most useful on value objects. 平等操作对价值对象最有用。 Also override the equality operators to make the equality comparison look natural. 还重写相等运算符以使相等比较看起来自然。

The implementation of the equality operations is trivial: Consider all data fields but disregard computed properties. 相等操作的实现很简单:考虑所有数据字段,但忽略计算的属性。 This will create purely content based equality operations. 这将创建纯粹基于内容的相等操作。

Since implementing equality operations on value objects is mechanistic, there is a library called Equ that does this automatically for you (which I wrote myself). 由于在值对象上实现相等操作是机制性的,因此有一个名为Equ会自动为您执行此操作(我自己写了)。 It will create equality operations at static instantiation time that have the same runtime performance as manually written Equals and GetHashCode implementations. 它将在静态实例化时间创建相等操作,这些操作具有与手动编写的EqualsGetHashCode实现相同的运行时性能。

Entities 实体

With entities, it gets a bit more tricky. 对于实体,它变得有些棘手。 The problem is that it is normally not really clear what equality means from a domain point of view . 问题在于, 从域的角度来看,通常通常并不清楚什么是平等。

Clearly, two Customer entities with different IDs are not equal. 显然,两个具有不同ID的Customer实体是不相等的。 But that's about it. 就是这样。 Are two Customer entities with the same ID, but in different state equal? 具有相同ID但状态不同的两个Customer实体是否相等? Difficult question. 难题。

The good news is that this kind of functionality in not really required. 好消息是这种功能并不是真正需要的。 So my advice is: Don't implement equality operations on entities. 因此,我的建议是: 不要对实体实施相等操作。

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

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