Skip to content

Instantly share code, notes, and snippets.

@ChrisMissal
Created June 5, 2013 16:06
Show Gist options
  • Select an option

  • Save ChrisMissal/5715101 to your computer and use it in GitHub Desktop.

Select an option

Save ChrisMissal/5715101 to your computer and use it in GitHub Desktop.
ValueObject<T>
[Serializable]
public abstract class ValueObject<T> : IEquatable<T> where T : class
{
public override bool Equals(object obj)
{
if (obj == null)
return false;
var other = obj as T;
return Equals(other);
}
public override int GetHashCode()
{
IEnumerable<FieldInfo> fields = GetFields();
const int startValue = 17;
const int multiplier = 59;
int hashCode = startValue;
foreach (FieldInfo field in fields)
{
object value = field.GetValue(this);
if (value != null)
hashCode = hashCode * multiplier + value.GetHashCode();
}
return hashCode;
}
public virtual bool Equals(T other)
{
if (other == null)
return false;
Type t = GetType();
FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (FieldInfo field in fields)
{
object value1 = null;
try
{
value1 = field.GetValue(other);
}
catch
{
// Swallow this one, value1 is defaulted to null
}
object value2 = field.GetValue(this);
if (value1 == null)
{
if (value2 != null)
return false;
}
else if (value2 == null)
{
return false;
}
else if ((typeof(DateTime).IsAssignableFrom(field.FieldType)) || ((typeof(DateTime?).IsAssignableFrom(field.FieldType))))
{
var dateString1 = ((DateTime)value1).ToLongDateString();
var dateString2 = ((DateTime)value2).ToLongDateString();
if (!dateString1.Equals(dateString2))
{
return false;
}
continue;
}
else if (!value1.Equals(value2))
return false;
}
return true;
}
private IEnumerable<FieldInfo> GetFields()
{
Type t = GetType();
var fields = new List<FieldInfo>();
while (t != typeof(object))
{
fields.AddRange(t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
t = t.BaseType;
}
return fields;
}
public static bool operator ==(ValueObject<T> x, ValueObject<T> y)
{
if (ReferenceEquals(x, null))
return ReferenceEquals(y, null);
return x.Equals(y);
}
public static bool operator !=(ValueObject<T> x, ValueObject<T> y)
{
return !(x == y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment