Пример #1
0
        /// <summary>
        /// Appends the fields and values defined by the given object of the given Class.
        /// </summary>
        /// <param name="builder">the builder to Append to</param>
        /// <param name="clazz">the class to Append details of</param>
        /// <param name="obj">the object to Append details of</param>
        /// <param name="useTransients">whether to use transient fields</param>
        private static void ReflectionAppend(object obj, Type clazz, HashCodeBuilder builder, bool useTransients)
        {
            //TODO: atrosin what does it mean? f.Name.IndexOf('$')
            //TODO: atrosin //AccessibleObject.setAccessible(fields, true);

            FieldInfo[] fields =
                clazz.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                                | BindingFlags.GetField);
            //AccessibleObject.setAccessible(fields, true);
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo f = fields[i];

                if ((f.Name.IndexOf('$') == -1) &&
                    (useTransients || !IsTransient(f)) &&
                    !f.IsStatic)
                {
                    try
                    {
                        builder.Append(f.GetValue(obj));
                    }
                    catch (Exception)
                    {
                        throw new Exception("Unexpected IllegalAccessException");
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        ///     This method uses reflection to build a valid hash code.
        ///
        ///     It uses AccessibleObject.setAccessible to gain access to private
        /// fields. This means that it will throw a security exception if run under
        /// a security manager, if the permissions are not set up correctly. It is also
        /// not as efficient as testing explicitly.
        ///
        ///     If the TestTransients parameter is set to true, transient
        /// members will be tested, otherwise they are ignored, as they are likely
        /// derived fields, and not part of the value of the Object.
        ///
        ///     Static fields will not be included. Superclass fields will be included
        /// up to and including the specified superclass. A null superclass is treated
        /// as java.lang.Object.
        ///
        ///     Two randomly chosen, non-zero, odd numbers must be passed in. Ideally
        /// these should be different for each class, however this is not vital.
        /// Prime numbers are preferred, especially for the multiplier.
        /// Throws IllegalArgumentException if the Object is null
        /// Throws IllegalArgumentException if the number is zero or even since 2.0
        /// </summary>
        /// <param name="initialNonZeroOddNumber">a non-zero, odd number used as the initial value</param>
        /// <param name="multiplierNonZeroOddNumber">a non-zero, odd number used as the multiplier</param>
        /// <param name="obj">the Object to create a hashCode for</param>
        /// <param name="reflectUpToClass">whether to include transient fields</param>
        /// <param name="testTransients">the superclass to reflect up to (inclusive),may be null</param>
        /// <returns>hash code</returns>
        public static int ReflectionHashCode(
            int initialNonZeroOddNumber,
            int multiplierNonZeroOddNumber,
            object obj,
            bool testTransients,
            Type reflectUpToClass)
        {
            if (obj == null)
            {
                throw new ArgumentException("The object to build a hash code for must not be null");
            }
            HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
            Type            clazz   = obj.GetType();

            ReflectionAppend(obj, clazz, builder, testTransients);
            while (clazz.BaseType != null && clazz != reflectUpToClass)
            {
                clazz = clazz.BaseType;
                ReflectionAppend(obj, clazz, builder, testTransients);
            }
            return(builder.ToHashCode());
        }