EqualsComparer
Comparator for a type that overrides Equals
using NUnit.Framework.Internal;
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Constraints.Comparers
{
[NullableContext(1)]
[Nullable(0)]
internal static class EqualsComparer
{
private static readonly Type[] EqualsObjectParameterTypes = new Type[1] {
typeof(object)
};
public static EqualMethodResult Equal(object x, object y, ref Tolerance tolerance, ComparisonState state, NUnitEqualityComparer equalityComparer)
{
if (equalityComparer.CompareAsCollection && state.TopLevelComparison)
return EqualMethodResult.TypesNotSupported;
Type type = x.GetType();
if (equalityComparer.CompareProperties && type.HasCompilerGeneratedEquals())
return EqualMethodResult.TypesNotSupported;
if (OverridesEqualsObject(type)) {
if (tolerance.HasVariance)
return EqualMethodResult.ToleranceNotSupported;
if (!x.Equals(y))
return EqualMethodResult.ComparedNotEqual;
return EqualMethodResult.ComparedEqual;
}
return EqualMethodResult.TypesNotSupported;
}
private static bool OverridesEqualsObject(Type type)
{
MethodInfo method = type.GetMethod("Equals", BindingFlags.Instance | BindingFlags.Public, null, EqualsObjectParameterTypes, null);
if ((object)method != null)
return method.DeclaringType != (type.IsValueType ? typeof(ValueType) : typeof(object));
return false;
}
}
}