patterncsharpMinor
Implementation of Equals and GetHashCode for base class
Viewed 0 times
forgethashcodeequalsandimplementationclassbase
Problem
Is this a good implementation for
```
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
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:
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)
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.