예제 #1
0
        public bool Equals(T x, T y)
        {
            var type = typeof(T);

            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            // Null?
            if (!type.IsValueType || (type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(NullableType)))
            {
                if (Object.Equals(x, default(T)))
                {
                    return(Object.Equals(y, default(T)));
                }

                if (Object.Equals(y, default(T)))
                {
                    return(false);
                }
            }

            if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y))
            {
                var tollerance = Tolerance.Empty;
                return(Numerics.AreEqual(x, y, ref tollerance));
            }

            // Implements IEquatable<T>?
            var equatable = x as IEquatable <T>;

            if (equatable != null)
            {
                return(equatable.Equals(y));
            }

            // Implements IComparable<T>?
            var comparableGeneric = x as IComparable <T>;

            if (comparableGeneric != null)
            {
                return(comparableGeneric.CompareTo(y) == 0);
            }

            // Implements IComparable?
            var comparable = x as IComparable;

            if (comparable != null)
            {
                try
                {
                    return(comparable.CompareTo(y) == 0);
                }
                catch (ArgumentException)
                {
                    // Thrown when two comparable types are not compatible, i.e string and int
                }
            }

            // Enumerable?
            var enumerableX = x as IEnumerable;
            var enumerableY = y as IEnumerable;

            if (enumerableX != null && enumerableY != null)
            {
                var enumeratorX      = enumerableX.GetEnumerator();
                var enumeratorY      = enumerableY.GetEnumerator();
                var equalityComparer = _innerComparerFactory();

                while (true)
                {
                    bool hasNextX = enumeratorX.MoveNext();
                    bool hasNextY = enumeratorY.MoveNext();

                    if (!hasNextX || !hasNextY)
                    {
                        return(hasNextX == hasNextY);
                    }

                    if (!equalityComparer.Equals(enumeratorX.Current, enumeratorY.Current))
                    {
                        return(false);
                    }
                }
            }

            // Last case, rely on Object.Equals
            return(Object.Equals(x, y));
        }
예제 #2
0
        public bool Equals(T?x, T?y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            if (x is null || y is null)
            {
                return(false);
            }

            if (Numerics.IsNumericType(x) &&
                Numerics.IsNumericType(y))
            {
                var tolerance = Tolerance.Empty;
                return(Numerics.AreEqual(x, y, ref tolerance));
            }

            // Enumerable?
            if (x.TryGetEnumerable(out var enumerableX) &&
                y.TryGetEnumerable(out var enumerableY))
            {
                var enumeratorX      = enumerableX.GetEnumerator();
                var enumeratorY      = enumerableY.GetEnumerator();
                var equalityComparer = _innerComparerFactory();

                while (true)
                {
                    var hasNextX = enumeratorX.MoveNext();
                    var hasNextY = enumeratorY.MoveNext();

                    if (!hasNextX || !hasNextY)
                    {
                        return(hasNextX == hasNextY);
                    }

                    if (!equalityComparer.Equals(enumeratorX.Current, enumeratorY.Current))
                    {
                        return(false);
                    }
                }
            }

            // Implements IEquatable<T>?
            if (x is IEquatable <T> equatable)
            {
                return(equatable.Equals(y));
            }

            // Implements IComparable<T>?
            if (x is IComparable <T> comparableGeneric)
            {
                return(comparableGeneric.CompareTo(y) == 0);
            }

            // Implements IComparable?
            if (x is IComparable comparable)
            {
                try
                {
                    return(comparable.CompareTo(y) == 0);
                }
                catch (ArgumentException)
                {
                    // Thrown when two comparable types are not compatible, i.e string and int
                }
            }

            // Last case, rely on Object.Equals
            return(object.Equals(x, y));
        }
예제 #3
0
 public void FailsOnIntegralsOutsideOfPercentage(object value)
 {
     Assert.IsTrue(Numerics.AreEqual(10000, value, ref tenPercent));
 }
예제 #4
0
        public bool AreEqual <T1, T2>(T1 x, T2 y, ref Tolerance tolerance)
        {
            Guard.OperationValid(CanCompare(x, y), "Invalid call");

            return(Numerics.AreEqual(x, y, ref tolerance));
        }
예제 #5
0
 public void CanMatchDecimalWithPercentage()
 {
     Assert.IsTrue(Numerics.AreEqual(10000m, 9500m, ref tenPercent));
     Assert.IsTrue(Numerics.AreEqual(10000m, 10000m, ref tenPercent));
     Assert.IsTrue(Numerics.AreEqual(10000m, 10500m, ref tenPercent));
 }
예제 #6
0
 public void CanMatchIntegralsWithPercentage(object value)
 {
     Assert.IsTrue(Numerics.AreEqual(10000, value, ref tenPercent));
 }
예제 #7
0
 public void CanMatchDecimalWithoutToleranceMode()
 {
     Assert.IsTrue(Numerics.AreEqual(123m, 123m, ref zeroTolerance));
 }
예제 #8
0
 public void CanMatchWithoutToleranceMode(object value)
 {
     Assert.IsTrue(Numerics.AreEqual(value, value, ref zeroTolerance));
 }
예제 #9
0
 public void FailsOnDecimalAbovePercentage()
 {
     Assert.IsTrue(Numerics.AreEqual(10000m, 11500m, ref tenPercent));
 }