<PackageReference Include="NUnit" Version="4.4.0-beta.1" />

PropertiesComparer

static class PropertiesComparer
Comparator for two instances of the same type, comparing each property.
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace NUnit.Framework.Constraints.Comparers { [NullableContext(1)] [Nullable(0)] internal static class PropertiesComparer { public static EqualMethodResult Equal(object x, object y, ref Tolerance tolerance, ComparisonState state, NUnitEqualityComparer equalityComparer) { Type xType = x.GetType(); Type yType = y.GetType(); PropertiesComparerConfiguration configuration = equalityComparer.ComparePropertiesConfiguration ?? PropertiesComparerConfiguration.Default; if (xType != yType && !configuration.AllowComparingDifferentTypes) return EqualMethodResult.TypesNotSupported; if (xType.IsPrimitive || yType.IsPrimitive) return EqualMethodResult.TypesNotSupported; PropertyInfo[] xProperties = xType.GetProperties(BindingFlags.Instance | BindingFlags.Public); HashSet<string> xPropertyNames = new HashSet<string>(from p in xProperties select p.Name); PropertyInfo[] source = xProperties; HashSet<string> yPropertyNames = xPropertyNames; HashSet<string> allPropertyNames = xPropertyNames; <>c__DisplayClass0_0 <>c__DisplayClass0_; if (xType != yType) { source = yType.GetProperties(BindingFlags.Instance | BindingFlags.Public); yPropertyNames = new HashSet<string>(from p in source select p.Name); allPropertyNames = new HashSet<string>(xPropertyNames.Concat(yPropertyNames)); <>c__DisplayClass0_.<Equal>g__UseProperties|7(yType, yPropertyNames); <>c__DisplayClass0_.<Equal>g__ExcludeProperties|8(yType, yPropertyNames); } <>c__DisplayClass0_.<Equal>g__UseProperties|7(xType, xPropertyNames); <>c__DisplayClass0_.<Equal>g__ExcludeProperties|8(xType, xPropertyNames); Dictionary<string, string> propertyNameMap = <>c__DisplayClass0_.<Equal>g__GetPropertyNameMap|9(); Dictionary<string, object> propertyNameToValueMap = <>c__DisplayClass0_.<Equal>g__GetPropertyToValueMap|10(); if (configuration.OnlyCompareCommonProperties && xPropertyNames != yPropertyNames) { xPropertyNames.IntersectWith(yPropertyNames); yPropertyNames = xPropertyNames; } int count = xPropertyNames.Count; int count2 = yPropertyNames.Count; Dictionary<string, object> dictionary = propertyNameToValueMap; if (count != count2 + ((dictionary != null) ? dictionary.Count : 0) || xPropertyNames.Count == 0) return EqualMethodResult.TypesNotSupported; xProperties = (from p in xProperties where xPropertyNames.Contains(p.Name) select p).ToArray(); source = (from p in source where yPropertyNames.Contains(p.Name) select p).ToArray(); if (xProperties.Any((PropertyInfo p) => p.GetIndexParameters().Length != 0) || source.Any((PropertyInfo p) => p.GetIndexParameters().Length != 0)) return EqualMethodResult.TypesNotSupported; ComparisonState state2 = state.PushComparison(x, y); BitArray bitArray = new BitArray(xProperties.Length); int num = 0; Dictionary<string, PropertyInfo> yPropertyDictionary = source.ToDictionary((PropertyInfo x) => x.Name); for (int i = 0; i < xProperties.Length; i++) { (string, object, string, object) valueTuple = <>c__DisplayClass0_.<Equal>g__GetPropertyNamesAndValues|11(i); string item = valueTuple.Item1; object item2 = valueTuple.Item2; string item3 = valueTuple.Item3; object item4 = valueTuple.Item4; Tolerance tolerance2 = tolerance; if (tolerance.IsUnsetOrDefault) { if ((item2 is TimeSpan || item2 is DateTime || item2 is DateTimeOffset) ? true : false) tolerance2 = configuration.TimeSpanTolerance; else if (Numerics.IsFloatingPointNumeric(item2)) { tolerance2 = configuration.FloatingPointTolerance; } else if (Numerics.IsFixedPointNumeric(item2)) { tolerance2 = configuration.FixedPointTolerance; } } switch (equalityComparer.AreEqual(item2, item4, ref tolerance2, state2)) { case EqualMethodResult.TypesNotSupported: case EqualMethodResult.ComparedNotEqual: return PropertyNotEqualResult(equalityComparer, i, xType.Name, item, item2, yType.Name, item3, item4); case EqualMethodResult.ToleranceNotSupported: bitArray.Set(i, true); num++; break; } } if (num == xProperties.Length) return EqualMethodResult.ToleranceNotSupported; if (num != 0) { Tolerance tolerance3 = Tolerance.Exact; for (int j = 0; j < xProperties.Length; j++) { if (bitArray.Get(j)) { (string, object, string, object) valueTuple2 = <>c__DisplayClass0_.<Equal>g__GetPropertyNamesAndValues|11(j); string item5 = valueTuple2.Item1; object item6 = valueTuple2.Item2; string item7 = valueTuple2.Item3; object item8 = valueTuple2.Item4; EqualMethodResult equalMethodResult = equalityComparer.AreEqual(item6, item8, ref tolerance3, state2); if (equalMethodResult == EqualMethodResult.ComparedNotEqual) return PropertyNotEqualResult(equalityComparer, j, xType.Name, item5, item6, yType.Name, item7, item8); } } } return EqualMethodResult.ComparedEqual; } private static EqualMethodResult PropertyNotEqualResult(NUnitEqualityComparer equalityComparer, int i, string xTypeName, string xPropertyName, [Nullable(2)] object xPropertyValue, string yTypeName, string yPropertyName, [Nullable(2)] object yPropertyValue) { NUnitEqualityComparer.FailurePoint obj = new NUnitEqualityComparer.FailurePoint { Position = i }; object propertyName; if (!(xTypeName == yTypeName)) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(6, 4); defaultInterpolatedStringHandler.AppendFormatted(xTypeName); defaultInterpolatedStringHandler.AppendLiteral("."); defaultInterpolatedStringHandler.AppendFormatted(xPropertyName); defaultInterpolatedStringHandler.AppendLiteral(" => "); defaultInterpolatedStringHandler.AppendFormatted(yTypeName); defaultInterpolatedStringHandler.AppendLiteral("."); defaultInterpolatedStringHandler.AppendFormatted(yPropertyName); propertyName = defaultInterpolatedStringHandler.ToStringAndClear(); } else propertyName = xTypeName + "." + xPropertyName; obj.PropertyName = (string)propertyName; obj.ExpectedHasData = true; obj.ExpectedValue = xPropertyValue; obj.ActualHasData = true; obj.ActualValue = yPropertyValue; NUnitEqualityComparer.FailurePoint item = obj; equalityComparer.FailurePoints.Insert(0, item); return EqualMethodResult.ComparedNotEqual; } } }