namespace Modules.Library.Domain.Entities; public abstract class Entity { private int? _requestedHashCode; public virtual Guid Id { get; protected set; } = Guid.NewGuid(); public virtual bool Deleted { get; protected set; } internal virtual void SetDeleted() => Deleted = true; public bool IsTransient() => Id == default; public override bool Equals(object? obj) { if (obj == null || obj is not Entity) return false; if (ReferenceEquals(this, obj)) return true; if (GetType() != obj.GetType()) return false; Entity item = (Entity)obj; if (item.IsTransient() || IsTransient()) return false; else return item.Id == Id; } public override int GetHashCode() { if (!IsTransient()) { if (!_requestedHashCode.HasValue) _requestedHashCode = Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) return _requestedHashCode.Value; } else return base.GetHashCode(); } public static bool operator ==(Entity? left, Entity? right) => Equals(left, null) ? Equals(right, null) : left.Equals(right); public static bool operator !=(Entity? left, Entity? right) { return !(left == right); } }