HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Implementation of Equals and GetHashCode for base class

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
forgethashcodeequalsandimplementationclassbase

Problem

Is this a good implementation for Equals and GetHashCode for a base class in C#? If it's not good enough, can you suggest improvements for it, please?

```
public abstract class Entity //TKey = Type of the Key
{
private string FullClassName;
private bool KeyIsNullable;
private Type BaseClassType;
private bool KeyIsComplex;

public abstract TKey Key { get; } //Key of the object, which determine it's uniqueness

public Entity()
{
FullClassName = GetType().FullName + "#";
KeyIsNullable = typeof(TKey).IsAssignableFrom(typeof(Nullable));
BaseClassType = typeof(Entity);
KeyIsComplex= !typeof(TKey).IsPrimitive;
}

public override bool Equals(object obj)
{
bool result = BaseClassType.IsAssignableFrom(obj.GetType());
result
= result
&& (
(
(
!KeyIsNullable
||
(Key != null && ((Entity)obj).Key != null
)
)
&&
Key.Equals(((Entity)obj).Key )
) // The key is not nullable, or (it's nullable but) both aren't null, and also equal
||
(
KeyIsNullable
&&
Key == null
&&
((Entity)obj).Key == null
)
); // Or the key is nullable, and both are null
return result;
}

public override int GetHashCode()
{
if ((KeyIsNullable&& Key == null) || (!KeyIsNullable&& Key .Equals(default(TKey))))
{
return base.GetHashCode();
}
string stringRepresentation = FullClassName + ((KeyIsComplex)? Key.GetHashCode().ToString() : Key.ToString());
return stringRe

Solution

I think you are overcomplicating things you can say simple this:

public abstract class Entity where TKey : struct 
    {
        public abstract TKey Key { get; }

        protected bool Equals(Entity other)
        {
            return Key.Equals(other.Key);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            var asThis = obj as Entity;
            return asThis != null && Equals(asThis);
        }

        public override int GetHashCode()
        {
            return Key.GetHashCode();
        }
    }


No need the type magic
A key cannot be null and it should be a ValueType
An Equals and GetHashCode implementation should be symmetric and fast (your solution is slow and i'm not sure it is symmetric or not)

Code Snippets

public abstract class Entity<TKey> where TKey : struct 
    {
        public abstract TKey Key { get; }

        protected bool Equals(Entity<TKey> other)
        {
            return Key.Equals(other.Key);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            var asThis = obj as Entity<TKey>;
            return asThis != null && Equals(asThis);
        }

        public override int GetHashCode()
        {
            return Key.GetHashCode();
        }
    }

Context

StackExchange Code Review Q#27421, answer score: 4

Revisions (0)

No revisions yet.