/// <summary>
        /// 确定指定的两个数组 <see cref="Array"/> 的所有元素的值是否递归相等。
        /// </summary>
        /// <param name="value">要进行值相等比较的第一个数组。</param>
        /// <param name="other">要进行值相等比较的第二个数组。</param>
        /// <param name="compared">当前已经比较过的对象的键值对。</param>
        /// <returns>若 <paramref name="value"/> 和 <paramref name="other"/>
        /// 均为数组 <see cref="Array"/>,且类型和尺寸相同,每个元素的值递归相等,
        /// 则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
        private static bool ArrayRecursiveEquals(
            Array value, Array other, HashSet <ObjectPair> compared)
        {
            if (value.Rank != other.Rank)
            {
                return(false);
            }
            if (value.Length != other.Length)
            {
                return(false);
            }
            for (int rank = 0; rank < value.Rank; rank++)
            {
                if (value.GetLength(rank) != other.GetLength(rank))
                {
                    return(false);
                }
            }

            var typeArray = value.GetType();

            if (typeArray.GetElementType() !.IsPointer)
            {
                var methodGet = typeArray.GetMethod("Get") !;
                for (int index = 0; index < value.Length; index++)
                {
                    var valueItem = methodGet.Invoke(value, value.OffsetToIndices(index).Box()) !;
                    var otherItem = methodGet.Invoke(other, other.OffsetToIndices(index).Box()) !;
                    if (!ObjectRuntimeValue.BoxedPointerEquals(valueItem, otherItem))
                    {
                        return(false);
                    }
                }
            }
        /// <summary>
        /// 确定指定的两个对象包含的值是否递归相等。
        /// </summary>
        /// <remarks>基于反射调用,可能存在性能问题。</remarks>
        /// <param name="value">要进行值相等比较的第一个对象。</param>
        /// <param name="other">要进行值相等比较的第二个对象。</param>
        /// <returns>若 <paramref name="value"/> 与 <paramref name="other"/> 包含的值递归相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        /// <exception cref="MemberAccessException">调用方没有权限来访问对象的成员。</exception>
        public static bool RecursiveEquals(object?value, object?other)
        {
            var comparer = PairReferenceEqualityComparer.Default;
            var compared = new HashSet <ObjectPair>(comparer);

            return(ObjectRuntimeValue.RecursiveEquals(value, other, compared));
        }
        /// <summary>
        /// 获取指定对象递归包含的值的哈希代码。
        /// </summary>
        /// <remarks>基于反射调用,可能存在性能问题。</remarks>
        /// <param name="value">要获取递归包含的值的哈希代码的对象。</param>
        /// <returns><paramref name="value"/> 递归包含的值的哈希代码。</returns>
        /// <exception cref="MemberAccessException">调用方没有权限来访问对象的成员。</exception>
        public static int GetRecursiveHashCode(object?value)
        {
            var comparer = ReferenceEqualityComparer.Default;
            var computed = new HashSet <object>(comparer);

            return(ObjectRuntimeValue.GetRecursiveHashCode(value, computed));
        }
        /// <summary>
        /// 获取指定对象递归包含的值的哈希代码。
        /// </summary>
        /// <param name="value">要获取基于值的哈希代码的对象。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="value"/> 递归包含的值的哈希代码。</returns>
        /// <exception cref="MemberAccessException">调用方没有权限来访问对象的成员。</exception>
        private static int GetRecursiveHashCode(object?value, HashSet <object> computed)
        {
            if (value is null)
            {
                return(0);
            }

            if (!computed.Add(value))
            {
                return(0);
            }

            var type = value.GetType();

            if (type.IsPrimitive)
            {
                return(ObjectRuntimeValue.GetPrimitiveHashCode(value));
            }
            if (type == typeof(string))
            {
                return(ObjectRuntimeValue.GetPrimitiveHashCode(value));
            }
            else if (type.IsArray)
            {
                return(ObjectRuntimeValue.GetArrayRecursiveHashCode((Array)value, computed));
            }
            else
            {
                return(ObjectRuntimeValue.GetObjectRecursiveHashCode(value, computed));
            }
        }
        /// <summary>
        /// 获取指定数组中所有元素的递归包含的值的哈希代码。
        /// </summary>
        /// <param name="value">要获取基于值的哈希代码的数组。</param>
        /// <param name="computed">已经计算过哈希代码的对象。</param>
        /// <returns><paramref name="value"/> 中所有元素的递归包含的值的哈希代码。</returns>
        /// <exception cref="MemberAccessException">调用方没有权限来访问对象的成员。</exception>
        private static int GetArrayRecursiveHashCode(Array value, HashSet <object> computed)
        {
            var hashCode = value.GetType().GetHashCode();

            var typeArray = value.GetType();

            if (typeArray.GetElementType() !.IsPointer)
            {
                var methodGet = typeArray.GetMethod("Get") !;
                for (int index = 0; index < value.Length; index++)
                {
                    var item = methodGet.Invoke(value, value.OffsetToIndices(index).Box()) !;
                    hashCode = ObjectRuntimeValue.CombineHashCode(
                        hashCode, ObjectRuntimeValue.GetBoxedPointerHashCode(item));
                }
            }
        /// <summary>
        /// 确定指定的两个对象包含的值是否递归相等。
        /// </summary>
        /// <param name="value">要进行值相等比较的第一个对象。</param>
        /// <param name="other">要进行值相等比较的第二个对象。</param>
        /// <param name="compared">当前已经比较过的对象的键值对。</param>
        /// <returns>若 <paramref name="value"/> 与 <paramref name="other"/> 包含的值递归相等,
        /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
        /// <exception cref="MemberAccessException">调用方没有权限来访问对象的成员。</exception>
        private static bool RecursiveEquals(
            object?value, object?other, HashSet <ObjectPair> compared)
        {
            if (RuntimeHelpers.Equals(value, other))
            {
                return(true);
            }
            if ((value is null) || (other is null))
            {
                return(false);
            }
            if (value.GetType() != other.GetType())
            {
                return(false);
            }

            var pair = new ObjectPair(value, other);

            if (!compared.Add(pair))
            {
                return(true);
            }

            var type = value.GetType();

            if (type.IsPrimitive)
            {
                return(ObjectRuntimeValue.PrimitiveEquals(value, other));
            }
            if (type == typeof(string))
            {
                return(ObjectRuntimeValue.PrimitiveEquals(value, other));
            }
            else if (type.IsArray)
            {
                return(ObjectRuntimeValue.ArrayRecursiveEquals((Array)value, (Array)other, compared));
            }
            else
            {
                return(ObjectRuntimeValue.ObjectRecursiveEquals(value, other, compared));
            }
        }
 /// <summary>
 /// 确定当前对象与指定对象的值是否相等。
 /// </summary>
 /// <remarks>基于反射调用,可能存在性能问题。
 /// 将递归比较至对象的字段(数组的元素)为 .NET 基元类型 (<see cref="Type.IsPrimitive"/>)、
 /// 字符串 <see cref="string"/> 或指针类型 (<see cref="Type.IsPointer"/>)。</remarks>
 /// <typeparam name="T">对象的类型。</typeparam>
 /// <param name="value">要进行值相等比较的对象。</param>
 /// <param name="other">要与当前对象进行比较的对象。</param>
 /// <returns>若 <paramref name="value"/> 与 <paramref name="other"/> 的值相等,
 /// 则为 <see langword="true"/>;否则为 <see langword="false"/>。</returns>
 public static bool ValueEquals <T>(this T?value, T?other) =>
 ObjectRuntimeValue.RecursiveEquals(value, other);
 public static T?SerializationClone <T>(this T?value) =>
 (T?)ObjectRuntimeValue.SerializationClone(value);
 public static T?RecursiveClone <T>(this T?value) =>
 (T?)ObjectRuntimeValue.RecursiveClone(value);
 public static T?DirectClone <T>(this T?value) =>
 (T?)ObjectRuntimeValue.DirectClone(value);