Tuesday, October 11, 2011

Generic IEqualityComparer - Comparing all properties on the object

public class GenericEqualityComparer : IEqualityComparer
{
private List _PropertyInfos = new List();

///
/// Creates a new instance of PropertyComparer.
///

/// The name of the property on type T
/// to perform the comparison on.
public GenericEqualityComparer()
{
var props = typeof(T).GetProperties(BindingFlags.GetProperty BindingFlags.Instance BindingFlags.Public);
_PropertyInfos.AddRange(props);
}

#region IEqualityComparer Members

public bool Equals(T x, T y)
{
foreach (var propertyInfo in _PropertyInfos)
{
//get the current value of the comparison property of x and of y
object xValue = propertyInfo.GetValue(x, null);
object yValue = propertyInfo.GetValue(y, null);

//if the xValue is null then we consider them equal if and only if yValue is null
if (xValue == null)
{
if (yValue != null)
return false;
}

if (!xValue.Equals(yValue))
return false;
}
return true;
}

public int GetHashCode(T obj)
{
List
`object`
values = new List();
foreach (var propertyInfo in _PropertyInfos)
{
//get the current value of the comparison property of x and of y
object xValue = propertyInfo.GetValue(obj, null);
values.Add(xValue);
}
return HashCodeBuilder.Hash(values.ToList());
}

#endregion
}

public static class HashCodeBuilder
{
public static int Hash(params object[] args)
{
if (args == null)
{
return 0;
}

int num = 42;

unchecked
{
foreach (var item in args)
{
if (ReferenceEquals(item, null))
{ }
else if (item.GetType().IsArray)
{
foreach (var subItem in (IEnumerable)item)
{
num = num * 37 + Hash(subItem);
}
}
else
{
num = num * 37 + item.GetHashCode();
}
}
}

return num;
}
}

No comments: