/// <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); } }
/// <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); } }