/// <inheritdoc />
 public int GetHashCode(
     object obj)
 {
     return(HashCodeHelper.Initialize().Hash(obj).Value);
 }
        /// <summary>
        /// Adds the hash code for the given item to the current hash code and returns the new hash code.
        /// </summary>
        /// <typeparam name="T">The type of the item being hashed.</typeparam>
        /// <param name="item">The item to hash.</param>
        /// <returns>The new hash code.</returns>
        public HashCodeHelper Hash <T>(
            T item)
        {
            unchecked
            {
                HashCodeHelper result;

                var declaredType = typeof(T);

                var runtimeType = item?.GetType();

                if ((declaredType == typeof(object)) && (runtimeType != null))
                {
                    // If the declared type is object and item is not null
                    // (if it's null then it will will eventually hit the else statement at the bottom,
                    // either in this pass, or thru HashDictionary(), etc. which will come back thru
                    // the front door using Hash<object>(null)
                    if (runtimeType == typeof(object))
                    {
                        // new object().GetHashCode() != new object().GetHashCode() so we need to solve for that here.
                        var hashCode = this.Value;

                        hashCode = (hashCode * HashCodeMultiplier) + ObjectHashCode;

                        result = new HashCodeHelper(hashCode);
                    }
                    else
                    {
                        // Use the runtime type as the declared type and come back thru the front door.
                        result = (HashCodeHelper)HashGenericMethodInfo.MakeGenericMethod(runtimeType).Invoke(this, new object[] { item });
                    }
                }
                else if (declaredType.IsClosedSystemDictionaryType())
                {
                    var methodInfo = declaredType.GetGenericTypeDefinition() == typeof(IDictionary <,>)
                        ? HashDictionaryGenericMethodInfo
                        : HashReadOnlyDictionaryGenericMethodInfo;

                    result = (HashCodeHelper)methodInfo.MakeGenericMethod(declaredType.GenericTypeArguments).Invoke(this, new object[] { item });
                }
                else if (declaredType.IsClosedSystemCollectionType())
                {
                    if (declaredType.IsClosedSystemOrderedCollectionType())
                    {
                        result = (HashCodeHelper)HashOrderedCollectionGenericMethodInfo.MakeGenericMethod(declaredType.GenericTypeArguments).Invoke(this, new object[] { item });
                    }
                    else
                    {
                        result = (HashCodeHelper)HashUnorderedCollectionGenericMethodInfo.MakeGenericMethod(declaredType.GenericTypeArguments).Invoke(this, new object[] { item });
                    }
                }
                else if (declaredType.IsArray)
                {
                    var genericArguments = declaredType.GetElementType();

                    result = (HashCodeHelper)HashOrderedCollectionGenericMethodInfo.MakeGenericMethod(genericArguments).Invoke(this, new object[] { item });
                }
                else if (declaredType.IsClosedSystemEnumerableType())
                {
                    result = (HashCodeHelper)HashUnorderedCollectionGenericMethodInfo.MakeGenericMethod(declaredType.GenericTypeArguments).Invoke(this, new object[] { item });
                }
                else if ((declaredType == typeof(DateTime)) || (declaredType == typeof(DateTime?)))
                {
                    var hashCode = this.Value;

                    hashCode = (hashCode * HashCodeMultiplier) + (item?.GetHashCode() ?? 0);

                    if (item != null)
                    {
                        hashCode = (hashCode * HashCodeMultiplier) + ((DateTime)(object)item).Kind.GetHashCode();
                    }

                    result = new HashCodeHelper(hashCode);
                }
                else if ((declaredType == typeof(Color)) || (declaredType == typeof(Color?)))
                {
                    if (item == null)
                    {
                        result = this.Hash((object)null);
                    }
                    else
                    {
                        var color = (Color)(object)item;

                        result = this.Hash(color.A).Hash(color.R).Hash(color.G).Hash(color.B);
                    }
                }
                else
                {
                    var hashCode = (this.Value * HashCodeMultiplier) + (item?.GetHashCode() ?? 0);

                    result = new HashCodeHelper(hashCode);
                }

                return(result);
            }
        }
Example #3
0
        /// <summary>
        /// Adds the hash code for the given item to the current hash code and returns the new hash code.
        /// </summary>
        /// <typeparam name="T">The type of the item being hashed.</typeparam>
        /// <param name="item">The item to hash.</param>
        /// <returns>The new hash code.</returns>
        public HashCodeHelper Hash <T>(
            T item)
        {
            unchecked
            {
                HashCodeHelper result;

                var valueType = typeof(T);

                if (valueType.IsClosedSystemDictionaryType())
                {
                    var methodInfo = valueType.GetGenericTypeDefinition() == typeof(IDictionary <,>)
                        ? HashDictionaryMethodInfo
                        : HashReadOnlyDictionaryMethodInfo;

                    result = (HashCodeHelper)methodInfo.MakeGenericMethod(valueType.GenericTypeArguments).Invoke(this, new[] { (object)item });
                }
                else if (valueType.IsClosedSystemCollectionType())
                {
                    if (valueType.IsClosedSystemOrderedCollectionType())
                    {
                        result = (HashCodeHelper)HashOrderedCollectionMethodInfo.MakeGenericMethod(valueType.GenericTypeArguments).Invoke(this, new[] { (object)item });
                    }
                    else
                    {
                        result = (HashCodeHelper)HashUnorderedCollectionMethodInfo.MakeGenericMethod(valueType.GenericTypeArguments).Invoke(this, new[] { (object)item });
                    }
                }
                else if (valueType.IsArray)
                {
                    var genericArguments = valueType.GetElementType();

                    result = (HashCodeHelper)HashOrderedCollectionMethodInfo.MakeGenericMethod(genericArguments).Invoke(this, new[] { (object)item });
                }
                else if (valueType.IsClosedSystemEnumerableType())
                {
                    result = (HashCodeHelper)HashUnorderedCollectionMethodInfo.MakeGenericMethod(valueType.GenericTypeArguments).Invoke(this, new[] { (object)item });
                }
                else if ((valueType == typeof(DateTime)) || (valueType == typeof(DateTime?)))
                {
                    var hashCode = this.Value;

                    hashCode = (hashCode * HashCodeMultiplier) + (item?.GetHashCode() ?? 0);

                    if (item != null)
                    {
                        hashCode = (hashCode * HashCodeMultiplier) + ((DateTime)(object)item).Kind.GetHashCode();
                    }

                    result = new HashCodeHelper(hashCode);
                }
                else
                {
                    var hashCode = (this.Value * HashCodeMultiplier) + (item?.GetHashCode() ?? 0);

                    result = new HashCodeHelper(hashCode);
                }

                return(result);
            }
        }