1+ using System ;
2+
3+ namespace Winton . DomainModelling
4+ {
5+ /// <inheritdoc />
6+ /// <summary>
7+ /// A base class to implement entity types, which are defined by their identity rather than their attributes.
8+ /// </summary>
9+ /// <typeparam name="TEntityId">The ID type for the entity type.</typeparam>
10+ public abstract class Entity < TEntityId > : IEquatable < Entity < TEntityId > >
11+ where TEntityId : IEquatable < TEntityId >
12+ {
13+ /// <summary>
14+ /// Initializes a new instance of the <see cref="Entity{TEntityId}" /> class.
15+ /// </summary>
16+ /// <param name="id">The ID for the entity.</param>
17+ protected Entity ( TEntityId id )
18+ {
19+ Id = id ;
20+ }
21+
22+ /// <summary>
23+ /// Gets the ID for the entity.
24+ /// </summary>
25+ public TEntityId Id { get ; }
26+
27+ /// <summary>
28+ /// Indicates whether two entities are equal.
29+ /// </summary>
30+ /// <param name="left">The first entity.</param>
31+ /// <param name="right">The second entity.</param>
32+ /// <returns><see langword="true" /> if the entities have the same ID; otherwise, <see langword="false" />.</returns>
33+ public static bool operator == ( Entity < TEntityId > left , Entity < TEntityId > right )
34+ {
35+ return Equals ( left , right ) ;
36+ }
37+
38+ /// <summary>
39+ /// Indicates whether two entities are unequal.
40+ /// </summary>
41+ /// <param name="left">The first entity.</param>
42+ /// <param name="right">The second entity.</param>
43+ /// <returns><see langword="true" /> if the entities have different IDs; otherwise, <see langword="false" />.</returns>
44+ public static bool operator != ( Entity < TEntityId > left , Entity < TEntityId > right )
45+ {
46+ return ! Equals ( left , right ) ;
47+ }
48+
49+ /// <inheritdoc />
50+ /// <summary>
51+ /// Indicates whether the current entity is equal to another entity.
52+ /// </summary>
53+ /// <param name="other">An entity to compare with this entity.</param>
54+ /// <returns>
55+ /// <see langword="true" /> if the current entity has the same ID as the <paramref name="other" /> entity;
56+ /// otherwise, <see langword="false" />.
57+ /// </returns>
58+ public bool Equals ( Entity < TEntityId > other )
59+ {
60+ if ( other is null )
61+ {
62+ return false ;
63+ }
64+
65+ if ( ReferenceEquals ( this , other ) )
66+ {
67+ return true ;
68+ }
69+
70+ if ( GetType ( ) != other . GetType ( ) )
71+ {
72+ return false ;
73+ }
74+
75+ return ! Id . Equals ( default ( TEntityId ) ) && ! other . Id . Equals ( default ( TEntityId ) ) && Id . Equals ( other . Id ) ;
76+ }
77+
78+ /// <summary>
79+ /// Determines whether the specified object is equal to the current object.
80+ /// </summary>
81+ /// <param name="obj">The object to compare with the current object.</param>
82+ /// <returns>
83+ /// <see langword="true" /> if the specified object is equal to the current object; otherwise,
84+ /// <see langword="false" />.
85+ /// </returns>
86+ public override bool Equals ( object obj )
87+ {
88+ return Equals ( obj as Entity < TEntityId > ) ;
89+ }
90+
91+ /// <summary>
92+ /// Serves as the default hash function.
93+ /// </summary>
94+ /// <returns>A hash code for the current object.</returns>
95+ public override int GetHashCode ( )
96+ {
97+ return Id . GetHashCode ( ) ;
98+ }
99+ }
100+ }
0 commit comments