public override IEnumerable <Difference> CalculateDifferences(Type type, object obj1, object obj2)
        {
            if (!type.InheritsFrom(typeof(HashSet <>)))
            {
                throw new ArgumentException("Invalid type");
            }

            if (!Settings.EmptyAndNullEnumerablesEqual &&
                (obj1 == null || obj2 == null) && obj1 != obj2)
            {
                yield break;
            }

            obj1 = obj1 ?? new HashSet <T>();
            obj2 = obj2 ?? new HashSet <T>();

            if (!obj1.GetType().InheritsFrom(typeof(HashSet <T>)))
            {
                throw new ArgumentException(nameof(obj1));
            }

            if (!obj2.GetType().InheritsFrom(typeof(HashSet <T>)))
            {
                throw new ArgumentException(nameof(obj2));
            }

            var hashSet1      = ((IEnumerable <T>)obj1).ToList();
            var hashSet2      = ((IEnumerable <T>)obj2).ToList();
            var valueComparer = OverridesCollection.GetComparer(typeof(T)) ?? DefaultValueComparer;

            foreach (var element in hashSet1)
            {
                if (!hashSet2.Contains(element))
                {
                    yield return(new Difference("", valueComparer.ToString(element), string.Empty,
                                                DifferenceTypes.MissedElementInSecondObject));
                }
            }

            foreach (var element in hashSet2)
            {
                if (!hashSet1.Contains(element))
                {
                    yield return(new Difference("", string.Empty, valueComparer.ToString(element),
                                                DifferenceTypes.MissedElementInFirstObject));
                }
            }
        }
Exemplo n.º 2
0
        public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
        {
            if (!Settings.EmptyAndNullEnumerablesEqual &&
                (obj1 == null || obj2 == null) && obj1 != obj2)
            {
                yield return new Difference("[]", obj1?.ToString() ?? string.Empty, obj2?.ToString() ?? string.Empty);
                yield break;
            }

            obj1 = obj1 ?? Enumerable.Empty<object>();
            obj2 = obj2 ?? Enumerable.Empty<object>();

            if (!type.InheritsFrom(typeof(IEnumerable)))
            {
                throw new ArgumentException(nameof(type));
            }

            if (!obj1.GetType().InheritsFrom(typeof(IEnumerable)))
            {
                throw new ArgumentException(nameof(obj1));
            }

            if (!obj2.GetType().InheritsFrom(typeof(IEnumerable)))
            {
                throw new ArgumentException(nameof(obj2));
            }

            var array1 = ((IEnumerable)obj1).Cast<object>().ToArray();
            var array2 = ((IEnumerable)obj2).Cast<object>().ToArray();

            if (array1.Length != array2.Length)
            {
                yield return new Difference("", array1.Length.ToString(), array2.Length.ToString(), DifferenceTypes.NumberOfElementsMismatch);
                yield break;
            }

            //ToDo Extract type
            for (var i = 0; i < array2.Length; i++)
            {
                if (array1[i] == null && array2[i] == null)
                {
                    continue;
                }

                var valueComparer1 = array1[i] != null ? OverridesCollection.GetComparer(array1[i].GetType()) ?? DefaultValueComparer : DefaultValueComparer;
                var valueComparer2 = array2[i] != null ? OverridesCollection.GetComparer(array2[i].GetType()) ?? DefaultValueComparer : DefaultValueComparer;

                if (array1[i] == null)
                {
                    yield return new Difference($"[{i}]", string.Empty, valueComparer2.ToString(array2[i]));
                    continue;
                }

                if (array2[i] == null)
                {
                    yield return new Difference($"[{i}]", valueComparer1.ToString(array1[i]), string.Empty);
                    continue;
                }

                if (array1[i].GetType() != array2[i].GetType())
                {
                    yield return new Difference($"[{i}]", valueComparer1.ToString(array1[i]), valueComparer2.ToString(array2[i]), DifferenceTypes.TypeMismatch);
                    continue;
                }

                var comparer = Factory.GetObjectsComparer(array1[i].GetType(), Settings, this);
                foreach (var failure in comparer.CalculateDifferences(array1[i].GetType(), array1[i], array2[i]))
                {
                    yield return failure.InsertPath($"[{i}]");
                }
            }
        }
        public override IEnumerable <Difference> CalculateDifferences(Type type, object obj1, object obj2)
        {
            var castedObject1 = (T)obj1;
            var castedObject2 = (T)obj2;
            var propertyKeys1 = GetProperties(castedObject1);
            var propertyKeys2 = GetProperties(castedObject2);

            var propertyKeys = propertyKeys1.Union(propertyKeys2);

            foreach (var propertyKey in propertyKeys)
            {
                var    existsInObject1 = propertyKeys1.Contains(propertyKey);
                var    existsInObject2 = propertyKeys2.Contains(propertyKey);
                object value1          = null;
                if (existsInObject1)
                {
                    TryGetMemberValue(castedObject1, propertyKey, out value1);
                }

                object value2 = null;
                if (existsInObject2)
                {
                    TryGetMemberValue(castedObject2, propertyKey, out value2);
                }

                var propertyType   = (value1 ?? value2)?.GetType() ?? typeof(object);
                var customComparer = OverridesCollection.GetComparer(propertyType) ??
                                     OverridesCollection.GetComparer(propertyKey);
                var valueComparer = customComparer ?? DefaultValueComparer;

                if (Settings.UseDefaultIfMemberNotExist)
                {
                    if (!existsInObject1)
                    {
                        value1 = propertyType.GetDefaultValue();
                    }

                    if (!existsInObject2)
                    {
                        value2 = propertyType.GetDefaultValue();
                    }
                }

                if (!Settings.UseDefaultIfMemberNotExist)
                {
                    if (!existsInObject1)
                    {
                        yield return(new Difference(propertyKey, string.Empty, valueComparer.ToString(value2),
                                                    DifferenceTypes.MissedMemberInFirstObject));

                        continue;
                    }

                    if (!existsInObject2)
                    {
                        yield return(new Difference(propertyKey, valueComparer.ToString(value1), string.Empty,
                                                    DifferenceTypes.MissedMemberInSecondObject));

                        continue;
                    }
                }

                if (value1 != null && value2 != null && value1.GetType() != value2.GetType())
                {
                    var valueComparer2 = OverridesCollection.GetComparer(value2.GetType()) ??
                                         OverridesCollection.GetComparer(propertyKey) ??
                                         DefaultValueComparer;
                    yield return(new Difference(propertyKey, valueComparer.ToString(value1), valueComparer2.ToString(value2),
                                                DifferenceTypes.TypeMismatch));

                    continue;
                }

                //null cannot be casted to ValueType
                if (value1 == null && value2 != null && value2.GetType().GetTypeInfo().IsValueType ||
                    value2 == null && value1 != null && value1.GetType().GetTypeInfo().IsValueType)
                {
                    var valueComparer2 = value2 != null?
                                         OverridesCollection.GetComparer(value2.GetType()) ?? OverridesCollection.GetComparer(propertyKey) ?? DefaultValueComparer:
                                         DefaultValueComparer;

                    yield return(new Difference(propertyKey, valueComparer.ToString(value1), valueComparer2.ToString(value2),
                                                DifferenceTypes.TypeMismatch));

                    continue;
                }

                if (customComparer != null)
                {
                    if (!customComparer.Compare(value1, value2, Settings))
                    {
                        yield return(new Difference(propertyKey, customComparer.ToString(value1), customComparer.ToString(value2)));
                    }

                    continue;
                }

                var comparer = Factory.GetObjectsComparer(propertyType, Settings, this);
                foreach (var failure in comparer.CalculateDifferences(propertyType, value1, value2))
                {
                    yield return(failure.InsertPath(propertyKey));
                }
            }
        }
Exemplo n.º 4
0
        internal IEnumerable <Difference> CalculateDifferences(T obj1, T obj2, MemberInfo memberInfo)
        {
            var comparer = memberInfo != null
                ? OverridesCollection.GetComparer(memberInfo)
                : OverridesCollection.GetComparer(typeof(T));

            if (typeof(T).IsComparable() ||
                comparer != null)
            {
                comparer = comparer ?? DefaultValueComparer;
                if (!comparer.Compare(obj1, obj2, Settings))
                {
                    yield return
                        (new Difference(string.Empty, comparer.ToString(obj1),
                                        comparer.ToString(obj2)));
                }

                yield break;
            }

            var conditionalComparer = _conditionalComparers.FirstOrDefault(c => c.IsMatch(typeof(T), obj1, obj2));

            if (conditionalComparer != null)
            {
                foreach (var difference in conditionalComparer.CalculateDifferences(typeof(T), obj1, obj2))
                {
                    yield return(difference);
                }

                if (conditionalComparer.IsStopComparison(typeof(T), obj1, obj2))
                {
                    yield break;
                }
            }

            if (obj1 == null || obj2 == null)
            {
                if (!DefaultValueComparer.Compare(obj1, obj2, Settings))
                {
                    yield return(new Difference(string.Empty, DefaultValueComparer.ToString(obj1), DefaultValueComparer.ToString(obj2)));
                }

                yield break;
            }

            if (!Settings.RecursiveComparison)
            {
                yield break;
            }

            foreach (var member in _members)
            {
                var value1 = member.GetMemberValue(obj1);
                var value2 = member.GetMemberValue(obj2);
                var type   = member.GetMemberType();

                if (conditionalComparer != null && conditionalComparer.SkipMember(typeof(T), member))
                {
                    continue;
                }

                var valueComparer     = DefaultValueComparer;
                var hasCustomComparer = false;

                var comparerOverride = OverridesCollection.GetComparer(member);
                if (comparerOverride != null)
                {
                    valueComparer     = comparerOverride;
                    hasCustomComparer = true;
                }

                if (!hasCustomComparer &&
                    !type.IsComparable())
                {
                    var objectDataComparer = Factory.GetObjectsComparer(type, Settings, this);

                    foreach (var failure in objectDataComparer.CalculateDifferences(type, value1, value2))
                    {
                        yield return(failure.InsertPath(member.Name));
                    }

                    continue;
                }

                if (!valueComparer.Compare(value1, value2, Settings))
                {
                    yield return(new Difference(member.Name, valueComparer.ToString(value1), valueComparer.ToString(value2)));
                }
            }
        }