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()); }
public static bool AreEqual(TypeReference a, TypeReference b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) { if (ReferenceEquals(a, b)) { return(true); } if (a == null || b == null) { return(false); } MetadataType aMetadataType = a.MetadataType; MetadataType bMetadataType = b.MetadataType; if (aMetadataType == MetadataType.GenericInstance || bMetadataType == MetadataType.GenericInstance) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual((GenericInstanceType)a, (GenericInstanceType)b, comparisonMode)); } if (aMetadataType == MetadataType.Array || bMetadataType == MetadataType.Array) { if (aMetadataType != bMetadataType) { return(false); } ArrayType a1 = (ArrayType)a; ArrayType b1 = (ArrayType)b; if (a1.Rank != b1.Rank) { return(false); } return(AreEqual(a1.ElementType, b1.ElementType, comparisonMode)); } if (aMetadataType == MetadataType.Var || bMetadataType == MetadataType.Var) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode)); } if (aMetadataType == MetadataType.MVar || bMetadataType == MetadataType.MVar) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual((GenericParameter)a, (GenericParameter)b, comparisonMode)); } if (aMetadataType == MetadataType.ByReference || bMetadataType == MetadataType.ByReference) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual(((ByReferenceType)a).ElementType, ((ByReferenceType)b).ElementType, comparisonMode)); } if (aMetadataType == MetadataType.Pointer || bMetadataType == MetadataType.Pointer) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual(((PointerType)a).ElementType, ((PointerType)b).ElementType, comparisonMode)); } if (aMetadataType == MetadataType.RequiredModifier || bMetadataType == MetadataType.RequiredModifier) { if (aMetadataType != bMetadataType) { return(false); } RequiredModifierType a1 = (RequiredModifierType)a; RequiredModifierType b1 = (RequiredModifierType)b; return(AreEqual(a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual(a1.ElementType, b1.ElementType, comparisonMode)); } if (aMetadataType == MetadataType.OptionalModifier || bMetadataType == MetadataType.OptionalModifier) { if (aMetadataType != bMetadataType) { return(false); } OptionalModifierType a1 = (OptionalModifierType)a; OptionalModifierType b1 = (OptionalModifierType)b; return(AreEqual(a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual(a1.ElementType, b1.ElementType, comparisonMode)); } if (aMetadataType == MetadataType.Pinned || bMetadataType == MetadataType.Pinned) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual(((PinnedType)a).ElementType, ((PinnedType)b).ElementType, comparisonMode)); } if (aMetadataType == MetadataType.Sentinel || bMetadataType == MetadataType.Sentinel) { if (aMetadataType != bMetadataType) { return(false); } return(AreEqual(((SentinelType)a).ElementType, ((SentinelType)b).ElementType, comparisonMode)); } if (!a.Name.Equals(b.Name) || !a.Namespace.Equals(b.Namespace)) { return(false); } TypeDefinition xDefinition = a.Resolve(); TypeDefinition yDefinition = b.Resolve(); // For loose signature the types could be in different assemblies, as long as the type names match we will consider them equal if (comparisonMode == TypeComparisonMode.SignatureOnlyLoose) { if (xDefinition.Module.Name != yDefinition.Module.Name) { return(false); } if (xDefinition.Module.Assembly.Name.Name != yDefinition.Module.Assembly.Name.Name) { return(false); } return(xDefinition.FullName == yDefinition.FullName); } return(xDefinition == yDefinition); }