public static int GetHashCodeFor(TypeReference obj) { // a very good prime number const int hashCodeMultiplier = 486187739; // prime numbers const int genericInstanceTypeMultiplier = 31; const int byReferenceMultiplier = 37; const int pointerMultiplier = 41; const int requiredModifierMultiplier = 43; const int optionalModifierMultiplier = 47; const int pinnedMultiplier = 53; const int sentinelMultiplier = 59; MetadataType metadataType = obj.MetadataType; if (metadataType == MetadataType.GenericInstance) { GenericInstanceType genericInstanceType = (GenericInstanceType)obj; int hashCode = GetHashCodeFor(genericInstanceType.ElementType) * hashCodeMultiplier + genericInstanceTypeMultiplier; for (int i = 0; i < genericInstanceType.GenericArguments.Count; i++) { hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(genericInstanceType.GenericArguments[i]); } return(hashCode); } if (metadataType == MetadataType.Array) { ArrayType arrayType = (ArrayType)obj; return(GetHashCodeFor(arrayType.ElementType) * hashCodeMultiplier + arrayType.Rank.GetHashCode()); } if (metadataType == MetadataType.Var || metadataType == MetadataType.MVar) { GenericParameter genericParameter = (GenericParameter)obj; int hashCode = genericParameter.Position.GetHashCode() * hashCodeMultiplier + ((int)metadataType).GetHashCode(); TypeReference ownerTypeReference = genericParameter.Owner as TypeReference; if (ownerTypeReference != null) { return(hashCode * hashCodeMultiplier + GetHashCodeFor(ownerTypeReference)); } MethodReference ownerMethodReference = genericParameter.Owner as MethodReference; if (ownerMethodReference != null) { return(hashCode * hashCodeMultiplier + MethodReferenceComparer.GetHashCodeFor(ownerMethodReference)); } throw new InvalidOperationException("Generic parameter encountered with invalid owner"); } if (metadataType == MetadataType.ByReference) { ByReferenceType byReferenceType = (ByReferenceType)obj; return(GetHashCodeFor(byReferenceType.ElementType) * hashCodeMultiplier * byReferenceMultiplier); } if (metadataType == MetadataType.Pointer) { PointerType pointerType = (PointerType)obj; return(GetHashCodeFor(pointerType.ElementType) * hashCodeMultiplier * pointerMultiplier); } if (metadataType == MetadataType.RequiredModifier) { RequiredModifierType requiredModifierType = (RequiredModifierType)obj; int hashCode = GetHashCodeFor(requiredModifierType.ElementType) * requiredModifierMultiplier; hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(requiredModifierType.ModifierType); return(hashCode); } if (metadataType == MetadataType.OptionalModifier) { OptionalModifierType optionalModifierType = (OptionalModifierType)obj; int hashCode = GetHashCodeFor(optionalModifierType.ElementType) * optionalModifierMultiplier; hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(optionalModifierType.ModifierType); return(hashCode); } if (metadataType == MetadataType.Pinned) { PinnedType pinnedType = (PinnedType)obj; return(GetHashCodeFor(pinnedType.ElementType) * hashCodeMultiplier * pinnedMultiplier); } if (metadataType == MetadataType.Sentinel) { SentinelType sentinelType = (SentinelType)obj; return(GetHashCodeFor(sentinelType.ElementType) * hashCodeMultiplier * sentinelMultiplier); } if (metadataType == MetadataType.FunctionPointer) { throw new NotImplementedException("We currently don't handle function pointer types."); } return(obj.Namespace.GetHashCode() * hashCodeMultiplier + obj.FullName.GetHashCode()); }
private static bool ContainsGenericParameters(TypeReference typeReference) { GenericParameter genericParameter = typeReference as GenericParameter; if (genericParameter != null) { return(true); } ArrayType arrayType = typeReference as ArrayType; if (arrayType != null) { return(ContainsGenericParameters(arrayType.ElementType)); } PointerType pointerType = typeReference as PointerType; if (pointerType != null) { return(ContainsGenericParameters(pointerType.ElementType)); } ByReferenceType byRefType = typeReference as ByReferenceType; if (byRefType != null) { return(ContainsGenericParameters(byRefType.ElementType)); } SentinelType sentinelType = typeReference as SentinelType; if (sentinelType != null) { return(ContainsGenericParameters(sentinelType.ElementType)); } PinnedType pinnedType = typeReference as PinnedType; if (pinnedType != null) { return(ContainsGenericParameters(pinnedType.ElementType)); } RequiredModifierType requiredModifierType = typeReference as RequiredModifierType; if (requiredModifierType != null) { return(ContainsGenericParameters(requiredModifierType.ElementType)); } GenericInstanceType genericInstance = typeReference as GenericInstanceType; if (genericInstance != null) { foreach (TypeReference genericArgument in genericInstance.GenericArguments) { if (ContainsGenericParameters(genericArgument)) { return(true); } } return(false); } if (typeReference is TypeSpecification) { throw new NotSupportedException(); } return(false); }