internal bool TryAdd(MemberInfo member, object xValue, object yValue) { Debug.Assert(!this.disposed, "this.disposed"); lock (this.gate) { if (this.KeyedSubBuilders.ContainsKey(member)) { this.Add(member, xValue, yValue); return(true); } if (!this.KeyedDiffs.TryGetValue(member, out var old)) { this.Add(member, xValue, yValue); return(true); } if (old.Diffs.Count > 0) { this.Add(member, xValue, yValue); return(true); } if (EqualBy.TryGetValueEquals(xValue, old.X, this.settings, out var xEqual) && xEqual && EqualBy.TryGetValueEquals(yValue, old.Y, this.settings, out var yEqual) && yEqual) { return(false); } this.Add(member, xValue, yValue); return(true); } }
internal static bool KeysAndValuesEquals( IReadOnlyDictionary <TKey, TValue> x, IReadOnlyDictionary <TKey, TValue> y, MemberSettings settings, ReferencePairCollection referencePairs) { foreach (var key in x.Keys) { var xv = x[key]; TValue yv; if (!y.TryGetValue(key, out yv)) { return(false); } if (referencePairs?.Contains(xv, yv) == true) { continue; } if (!EqualBy.MemberValues(xv, yv, settings, referencePairs)) { return(false); } } return(true); }
private static void Members <T>(T source, T target, MemberSettings settings, ReferencePairCollection referencePairs) { Debug.Assert(source != null, nameof(source)); Debug.Assert(target != null, nameof(target)); Debug.Assert(source.GetType() == target.GetType(), "Must be same type"); using (var borrowed = ListPool <IGetterAndSetter> .Borrow()) { foreach (var member in settings.GetMembers(source.GetType())) { if (settings.IsIgnoringMember(member)) { continue; } var getterAndSetter = settings.GetOrCreateGetterAndSetter(member); Member(source, target, settings, referencePairs, getterAndSetter); if (getterAndSetter.IsInitOnly) { borrowed.Value.Add(getterAndSetter); } } foreach (var getterAndSetter in borrowed.Value) { var sv = getterAndSetter.GetValue(source); var tv = getterAndSetter.GetValue(target); if (!EqualBy.MemberValues(sv, tv, settings)) { Throw.ReadonlyMemberDiffers(new SourceAndTargetValue(source, sv, target, tv), getterAndSetter.Member, settings); } } } }
/// <inheritdoc /> public override bool Equals( object x, object y, MemberSettings settings, ReferencePairCollection referencePairs) { bool result; if (TryGetEitherNullEquals(x, y, out result)) { return(result); } var xs = (ISet <T>)x; var ys = (ISet <T>)y; if (xs.Count != ys.Count) { return(false); } var isEquatable = settings.IsEquatable(x.GetType().GetItemType()); var xHashSet = xs as HashSet <T>; if (isEquatable) { if (Equals(xHashSet?.Comparer, EqualityComparer <T> .Default)) { return(xs.SetEquals(ys)); } return(this.ItemsEquals(xs, ys, EqualityComparer <T> .Default.Equals, EqualityComparer <T> .Default.GetHashCode)); } if (settings.ReferenceHandling == ReferenceHandling.References) { return(this.ItemsEquals(xs, ys, (xi, yi) => ReferenceEquals(xi, yi), xi => RuntimeHelpers.GetHashCode(xi))); } var hashCodeMethod = typeof(T).GetMethod(nameof(this.GetHashCode), new Type[0]); if (hashCodeMethod.DeclaringType == typeof(object)) { return(this.ItemsEquals(xs, ys, (xi, yi) => EqualBy.MemberValues(xi, yi, settings, referencePairs), _ => 0)); } return(this.ItemsEquals(xs, ys, (xi, yi) => EqualBy.MemberValues(xi, yi, settings, referencePairs), xi => xi.GetHashCode())); }
// ReSharper disable once UnusedParameter.Local private void AddDiffs( DiffBuilder collectionBuilder, ISet <T> x, ISet <T> y, MemberSettings settings) { if (typeof(T).Implements <IEquatable <T> >()) { using (var borrow = HashSetPool <T> .Borrow(EqualityComparer <T> .Default.Equals, EqualityComparer <T> .Default.GetHashCode)) { AddItemDiffs(collectionBuilder, x, y, borrow.Value); return; } } switch (settings.ReferenceHandling) { case ReferenceHandling.Throw: throw Throw.ShouldNeverGetHereException("ReferenceHandling should be checked before"); case ReferenceHandling.References: using (var borrow = HashSetPool <T> .Borrow((xi, yi) => ReferenceEquals(xi, yi), item => RuntimeHelpers.GetHashCode(item))) { AddItemDiffs(collectionBuilder, x, y, borrow.Value); return; } case ReferenceHandling.Structural: using (var borrow = HashSetPool <T> .Borrow((xi, yi) => EqualBy.MemberValues(xi, yi, settings), xi => 0)) { AddItemDiffs(collectionBuilder, x, y, borrow.Value); return; } default: throw new ArgumentOutOfRangeException(); } }
private static bool Equals( IList <T> x, IList <T> y, MemberSettings settings, ReferencePairCollection referencePairs) { for (var i = 0; i < x.Count; i++) { var xv = x[i]; var yv = y[i]; if (referencePairs?.Contains(xv, yv) == true) { continue; } if (!EqualBy.MemberValues(xv, yv, settings, referencePairs)) { return(false); } } return(true); }
private static bool Equals( Array x, Array y, MemberSettings settings, ReferencePairCollection referencePairs) { if (!Is.SameSize(x, y)) { return(false); } var isEquatable = settings.IsEquatable(x.GetType().GetItemType()); if (settings.ReferenceHandling == ReferenceHandling.References) { return(isEquatable ? ItemsEquals(x, y, Equals) : ItemsEquals(x, y, ReferenceEquals)); } return(isEquatable ? ItemsEquals(x, y, Equals) : ItemsEquals(x, y, (xi, yi) => EqualBy.MemberValues(xi, yi, settings, referencePairs))); }
public bool TryGetValueEquals(TSource x, TSource y, MemberSettings settings, out bool equal, out TValue xv, out TValue yv) { xv = this.GetValue(x); yv = this.GetValue(y); return(EqualBy.TryGetValueEquals(xv, yv, settings, out equal)); }
/// <inheritdoc /> public override bool Equals( object x, object y, MemberSettings settings, ReferencePairCollection referencePairs) { bool result; if (TryGetEitherNullEquals(x, y, out result)) { return(result); } var isEquatable = settings.IsEquatable(typeof(T)); if (settings.ReferenceHandling == ReferenceHandling.References) { return(isEquatable ? ItemsEquals((IEnumerable <T>)x, (IEnumerable <T>)y, EqualityComparer <T> .Default.Equals) : ItemsEquals((IEnumerable <T>)x, (IEnumerable <T>)y, (xi, yi) => ReferenceEquals(xi, yi))); } return(isEquatable ? ItemsEquals((IEnumerable <T>)x, (IEnumerable <T>)y, EqualityComparer <T> .Default.Equals) : ItemsEquals((IEnumerable <T>)x, (IEnumerable <T>)y, (xi, yi) => EqualBy.MemberValues(xi, yi, settings, referencePairs))); }