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; var metadataType = obj.MetadataType; if (metadataType == MetadataType.GenericInstance) { var genericInstanceType = (GenericInstanceType)obj; var hashCode = GetHashCodeFor(genericInstanceType.ElementType) * hashCodeMultiplier + genericInstanceTypeMultiplier; for (var i = 0; i < genericInstanceType.GenericArguments.Count; i++) { hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(genericInstanceType.GenericArguments[i]); } return(hashCode); } if (metadataType == MetadataType.Array) { var arrayType = (ArrayType)obj; return(GetHashCodeFor(arrayType.ElementType) * hashCodeMultiplier + arrayType.Rank.GetHashCode()); } if (metadataType == MetadataType.Var || metadataType == MetadataType.MVar) { var genericParameter = (GenericParameter)obj; var hashCode = genericParameter.Position.GetHashCode() * hashCodeMultiplier + ((int)metadataType).GetHashCode(); var ownerTypeReference = genericParameter.Owner as TypeReference; if (ownerTypeReference != null) { return(hashCode * hashCodeMultiplier + GetHashCodeFor(ownerTypeReference)); } var 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) { var byReferenceType = (ByReferenceType)obj; return(GetHashCodeFor(byReferenceType.ElementType) * hashCodeMultiplier * byReferenceMultiplier); } if (metadataType == MetadataType.Pointer) { var pointerType = (PointerType)obj; return(GetHashCodeFor(pointerType.ElementType) * hashCodeMultiplier * pointerMultiplier); } if (metadataType == MetadataType.RequiredModifier) { var requiredModifierType = (RequiredModifierType)obj; var hashCode = GetHashCodeFor(requiredModifierType.ElementType) * requiredModifierMultiplier; hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(requiredModifierType.ModifierType); return(hashCode); } if (metadataType == MetadataType.OptionalModifier) { var optionalModifierType = (OptionalModifierType)obj; var hashCode = GetHashCodeFor(optionalModifierType.ElementType) * optionalModifierMultiplier; hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor(optionalModifierType.ModifierType); return(hashCode); } if (metadataType == MetadataType.Pinned) { var pinnedType = (PinnedType)obj; return(GetHashCodeFor(pinnedType.ElementType) * hashCodeMultiplier * pinnedMultiplier); } if (metadataType == MetadataType.Sentinel) { var 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()); }
static bool AreEqual(GenericParameter a, GenericParameter b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) { if (ReferenceEquals(a, b)) { return(true); } if (a.Position != b.Position) { return(false); } if (a.Type != b.Type) { return(false); } var aOwnerType = a.Owner as TypeReference; if (aOwnerType != null && AreEqual(aOwnerType, b.Owner as TypeReference, comparisonMode)) { return(true); } var aOwnerMethod = a.Owner as MethodReference; if (aOwnerMethod != null && comparisonMode != TypeComparisonMode.SignatureOnlyLoose && MethodReferenceComparer.AreEqual(aOwnerMethod, b.Owner as MethodReference)) { return(true); } return(comparisonMode == TypeComparisonMode.SignatureOnly || comparisonMode == TypeComparisonMode.SignatureOnlyLoose); }