internal static void UpdateCollectionItemDiff(
            this DiffBuilder collectionBuilder,
            object xItem,
            object yItem,
            object index,
            MemberSettings settings)
        {
            ValueDiff diff;

            if (TryGetValueDiff(xItem, yItem, settings, out diff))
            {
                if (diff != null)
                {
                    collectionBuilder.Add(new IndexDiff(index, diff));
                }
                else
                {
                    collectionBuilder.Remove(index);
                }

                return;
            }

            if (settings.ReferenceHandling == ReferenceHandling.References)
            {
                if (ReferenceEquals(xItem, yItem))
                {
                    collectionBuilder.Remove(index);
                }
                else
                {
                    collectionBuilder.Add(new IndexDiff(index, new ValueDiff(xItem, yItem)));
                }

                return;
            }

            IRefCounted <DiffBuilder> subDiffBuilder;

            if (DiffBuilder.TryCreate(xItem, yItem, settings, out subDiffBuilder))
            {
                subDiffBuilder.Value.UpdateDiffs(xItem, yItem, settings);
            }

            collectionBuilder.AddLazy(index, subDiffBuilder.Value);
        }
示例#2
0
        internal static void UpdateMemberDiff(
            this DiffBuilder builder,
            object xSource,
            object ySource,
            MemberInfo member,
            MemberSettings settings)
        {
            if (settings.IsIgnoringMember(member))
            {
                return;
            }

            var getterAndSetter = settings.GetOrCreateGetterAndSetter(member);

            if (getterAndSetter.TryGetValueEquals(xSource, ySource, settings, out var equal, out var xValue, out var yValue))
            {
                if (equal)
                {
                    builder.Remove(member);
                }
                else
                {
                    builder.TryAdd(member, xValue, yValue);
                }

                return;
            }

            switch (settings.ReferenceHandling)
            {
            case ReferenceHandling.References:
                if (ReferenceEquals(xValue, yValue))
                {
                    builder.Remove(member);
                }
                else
                {
                    builder.TryAdd(member, xValue, yValue);
                }

                return;

            case ReferenceHandling.Structural:
                IRefCounted <DiffBuilder> subDiffBuilder;
                if (DiffBuilder.TryCreate(xValue, yValue, settings, out subDiffBuilder))
                {
                    subDiffBuilder.Value.UpdateDiffs(xValue, yValue, settings);
                }

                builder.AddLazy(member, subDiffBuilder.Value);
                return;

            case ReferenceHandling.Throw:
                throw Throw.ShouldNeverGetHereException();

            default:
                throw new ArgumentOutOfRangeException(
                          nameof(settings.ReferenceHandling),
                          settings.ReferenceHandling,
                          null);
            }
        }