示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
                    }
                }
            }
        }
示例#4
0
        /// <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()));
        }
示例#5
0
        // 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();
            }
        }
示例#6
0
        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)));
        }
示例#8
0
 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)));
        }