/// <summary>
        /// 获取指定的 <see cref="DictionaryEntry"/> 中的键值的哈希代码。
        /// </summary>
        /// <param name="obj">要为其获取哈希代码的 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="obj"/> 中的键值的哈希代码。</returns>
        protected override int GetHashCodeCore(DictionaryEntry obj, ISet <object> computed)
        {
            var keyComparer   = StructuralEqualityComparer.OfType(obj.Key?.GetType());
            var valueComparer = StructuralEqualityComparer.OfType(obj.Value?.GetType());

            return(this.CombineHashCode(
                       keyComparer.GetHashCode(obj, computed),
                       valueComparer.GetHashCode(obj, computed)));
        }
        /// <summary>
        /// 获取指定的 <see cref="IEnumerable"/> 中的元素的哈希代码。
        /// </summary>
        /// <param name="obj">要获取哈希代码的 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="obj"/> 中的元素的哈希代码。</returns>
        protected override int GetHashCodeCore(T obj, ISet <object> computed)
        {
            var hashCode = obj.GetType().GetHashCode();

            foreach (var item in obj)
            {
                var comparer     = StructuralEqualityComparer.OfType(item?.GetType());
                var nextHashCode = comparer.GetHashCode(item !, computed);
                hashCode = this.CombineHashCode(hashCode, nextHashCode);
            }
            return(hashCode);
        }
        /// <summary>
        /// 获取指定的数组中的元素的哈希代码。
        /// </summary>
        /// <param name="obj">要获取哈希代码的数组。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="obj"/> 中的元素的哈希代码。</returns>
        protected override int GetHashCodeCore(TItem[] obj, ISet <object> computed)
        {
            var length   = obj.Length;
            var hashCode = obj.GetType().GetHashCode();

            for (int index = 0; index < length; index++)
            {
                var comparer     = StructuralEqualityComparer.OfType(obj[index]?.GetType());
                var nextHashCode = comparer.GetHashCode(obj[index] !);
                hashCode = this.CombineHashCode(hashCode, nextHashCode);
            }
            return(hashCode);
        }
Beispiel #4
0
        /// <summary>
        /// 获取指定的数组中的元素的哈希代码。
        /// </summary>
        /// <param name="obj">要获取哈希代码的数组。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="obj"/> 中的元素的哈希代码。</returns>
        protected override int GetHashCodeCore([DisallowNull] T obj, ISet <object> computed)
        {
            var array = (Array)(object)obj;

            var hashCode = array.GetType().GetHashCode();

            for (int index = 0; index < array.Length; index++)
            {
                var item     = array.GetValue(array.OffsetToIndices(index));
                var comparer = StructuralEqualityComparer.OfType(item?.GetType());
                hashCode = this.CombineHashCode(
                    hashCode, comparer.GetHashCode(item !, computed));
            }
            return(hashCode);
        }
        /// <summary>
        /// 确定两个指定的 <see cref="DictionaryEntry"/> 中的键值是否相等。
        /// </summary>
        /// <param name="x">要比较的第一个 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="y">要比较的第二个 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="compared">已经比较过的对象。</param>
        /// <returns>如果 <paramref name="x"/> 和 <paramref name="y"/> 中的键值相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        protected override bool EqualsCore(
            DictionaryEntry x, DictionaryEntry y, ISet <ObjectPair> compared)
        {
            if (x.Key?.GetType() != y.Key?.GetType())
            {
                return(false);
            }
            if (x.Value?.GetType() != y.Value?.GetType())
            {
                return(false);
            }

            var keyComparer   = StructuralEqualityComparer.OfType(x.Key?.GetType());
            var valueComparer = StructuralEqualityComparer.OfType(x.Value?.GetType());

            return(keyComparer.Equals(x.Key, y.Key, compared) &&
                   valueComparer.Equals(x.Value, y.Value, compared));
        }
        /// <summary>
        /// 确定两个指定的 <see cref="IEnumerable"/> 中的元素是否相等。
        /// </summary>
        /// <param name="x">要比较的第一个 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="y">要比较的第二个 <see cref="IEnumerable"/> 对象。</param>
        /// <param name="compared">已经比较过的对象。</param>
        /// <returns>如果 <paramref name="x"/> 和 <paramref name="y"/> 中的元素相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        protected override bool EqualsCore(T x, T y, ISet <ObjectPair> compared)
        {
            if ((x is ICollection <T> xCollection) &&
                (y is ICollection <T> yCollection))
            {
                if (xCollection.Count != yCollection.Count)
                {
                    return(false);
                }
            }

            var xEnumerator = x.GetEnumerator();
            var yEnumerator = y.GetEnumerator();

            try
            {
                bool xHasNext, yHasNext;
                while ((xHasNext = xEnumerator.MoveNext()) &
                       (yHasNext = yEnumerator.MoveNext()))
                {
                    var xItem = xEnumerator.Current;
                    var yItem = yEnumerator.Current;

                    if (xItem?.GetType() != yItem?.GetType())
                    {
                        return(false);
                    }

                    var comparer = StructuralEqualityComparer.OfType(xItem?.GetType());
                    if (!comparer.Equals(xItem, yItem, compared))
                    {
                        return(false);
                    }
                }
                return(xHasNext == yHasNext);
            }
            finally
            {
                (xEnumerator as IDisposable)?.Dispose();
                (yEnumerator as IDisposable)?.Dispose();
            }
        }
Beispiel #7
0
        /// <summary>
        /// 确定两个指定数组中所包含的元素是否相等。
        /// </summary>
        /// <param name="x">要比较的第一个数组。</param>
        /// <param name="y">要比较的第二个数组。</param>
        /// <param name="compared">已经比较过的对象。</param>
        /// <returns>如果 <paramref name="x"/> 和 <paramref name="y"/> 中的元素相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        protected override bool EqualsCore(
            [DisallowNull] T x, [DisallowNull] T y, ISet <ObjectPair> compared)
        {
            var xArray = (Array)(object)x;
            var yArray = (Array)(object)y;

            if (xArray.Rank != yArray.Rank)
            {
                return(false);
            }
            if (xArray.Length != yArray.Length)
            {
                return(false);
            }
            for (int rank = 0; rank < xArray.Rank; rank++)
            {
                if (xArray.GetLength(rank) != yArray.GetLength(rank))
                {
                    return(false);
                }
            }

            for (int index = 0; index < xArray.Length; index++)
            {
                var xItem = xArray.GetValue(xArray.OffsetToIndices(index));
                var yItem = yArray.GetValue(yArray.OffsetToIndices(index));

                if (xItem?.GetType() != yItem?.GetType())
                {
                    return(false);
                }

                var comparer = StructuralEqualityComparer.OfType(xItem?.GetType());
                if (!comparer.Equals(xItem, yItem, compared))
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// 确定两个指定数组中的元素是否相等。
        /// </summary>
        /// <param name="x">要比较的第一个数组。</param>
        /// <param name="y">要比较的第二个数组。</param>
        /// <param name="compared">已经比较过的对象。</param>
        /// <returns>如果 <paramref name="x"/> 和 <paramref name="y"/> 的元素相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        protected override bool EqualsCore(TItem[] x, TItem[] y, ISet <ObjectPair> compared)
        {
            if (x.Length != y.Length)
            {
                return(false);
            }

            var length = x.Length;

            for (int index = 0; index < length; index++)
            {
                if (x[index]?.GetType() != y[index]?.GetType())
                {
                    return(false);
                }

                var comparer = StructuralEqualityComparer.OfType(x[index]?.GetType());
                if (!comparer.Equals(x[index], y[index], compared))
                {
                    return(false);
                }
            }
            return(true);
        }