简体   繁体   中英

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.

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.

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.

3) How about Equals for Entities ?

Is it a good idea to override Equals and only compare the id properties ? 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 .

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). It will create equality operations at static instantiation time that have the same runtime performance as manually written Equals and GetHashCode implementations.

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. But that's about it. Are two Customer entities with the same ID, but in different state equal? 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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