private static void reflectionAppend( Object lhs, Object rhs, Type type, EqualsBuilder builder, bool useTransients, IEnumerable <string> excludedFields) { if (isRegistered(lhs, rhs)) { return; } try { REGISTRY.Value.Add(Tuple.Create(new IDKey(lhs), new IDKey(rhs))); var values = type .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(prop => prop.CanWrite) .Select(prop => new { lhs = prop.GetValue(lhs, null), rhs = prop.GetValue(rhs, null) }); foreach (var value in values) { builder.append(value.lhs, value.rhs); } } finally { REGISTRY.Value.Remove(Tuple.Create(new IDKey(lhs), new IDKey(rhs))); } }
public static bool reflectionEquals(Type type, Object lhs, Object rhs, bool testTransients, IEnumerable <String> excludedFields) { if (lhs == rhs) { return(true); } if (lhs == null || rhs == null) { return(false); } var lhsClass = lhs.GetType(); var rhsClass = rhs.GetType(); if (!lhsClass.IsInstanceOfType(rhs) && !rhsClass.IsInstanceOfType(lhs)) { // The two classes are not related. return(false); } EqualsBuilder equalsBuilder = new EqualsBuilder(); try { reflectionAppend(lhs, rhs, type, equalsBuilder, testTransients, excludedFields); while (type.BaseType != null) { type = type.BaseType; reflectionAppend(lhs, rhs, type, equalsBuilder, testTransients, excludedFields); } } catch (ArgumentException e) { // In this case, we tried to test a subclass vs. a superclass and // the subclass has ivars or the ivars are transient and // we are testing transients. // If a subclass has ivars that we are trying to test them, we get an // exception and we know that the objects are not equal. return(false); } return(equalsBuilder.value); }