It is usually a recommended practice to have Value-Object base-class so we can have common functionality which can be used by all of our value-object classes. Typically, comparison methods or any other common subject for Value-Objects, should be included here.
Below I show a sample Value-Object Base-Class:
public class ValueObject<TValueObject> : IEquatable<TValueObject>
where TValueObject : ValueObject<TValueObject>
{
public bool Equals(TValueObject other)
{
if ((object)other == null)
return false;
//compare all public properties
PropertyInfo[] publicProperties = this.GetType().GetProperties();
if ((object)publicProperties != null
&&
publicProperties.Any())
{
bool result = true;
foreach (var item in publicProperties)
{
//compare two values using default equatable method
if (!item.GetValue(this, null).Equals(item.GetValue(other, null)))
{
result = false;
break;
}
}
return result;
}
else
return true;
}
public override bool Equals(object obj)
{
if ((object)obj == null)
return false;
ValueObject<TValueObject> item = obj as ValueObject<TValueObject>;
if ((object)item != null)
return Equals((TValueObject)item);
else
return false;
}
public override int GetHashCode()
{
int hashCode = 31;
bool changeMultiplier = false;
int index = 1;
//compare all public properties
PropertyInfo[] publicProperties = this.GetType().GetProperties();
if ((object)publicProperties != null
&&
publicProperties.Any())
{
foreach (var item in publicProperties)
{
object value = item.GetValue(this, null);
if ((object)value != null)
{
hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode();
changeMultiplier = !changeMultiplier;
}
else
hashCode = hashCode ^ (index * 13);//only for support {"a",null,null,"a"} <> {null,"a","a",null}
}
}
return hashCode;
}
public static bool operator ==(ValueObject<TValueObject> x, ValueObject<TValueObject> y)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(x, y))
{
return true;
}
// If one is null, but not both, return false.
if (((object)x == null) || ((object)y == null))
{
return false;
}
// Return true if the fields match:
return x.Equals(y);
}
public static bool operator !=(ValueObject<TValueObject> x, ValueObject<TValueObject> y)
{
return !(x == y);
}
}
0 comments