/// <summary> /// This is semantically identical to /// /// actual == pattern.TryResolveAgainstGenericMethod(parameterMember) /// /// but without the allocation overhead of TryResolve. /// </summary> internal static bool MatchesExactly(this SignatureType pattern, Type actual) { if (pattern.IsSZArray) { return(actual.IsSZArray && pattern.ElementType !.MatchesExactly(actual.GetElementType() !)); } else if (pattern.IsVariableBoundArray) { return(actual.IsVariableBoundArray && pattern.GetArrayRank() == actual.GetArrayRank() && pattern.ElementType !.MatchesExactly(actual.GetElementType() !)); } else if (pattern.IsByRef) { return(actual.IsByRef && pattern.ElementType !.MatchesExactly(actual.GetElementType() !)); } else if (pattern.IsPointer) { return(actual.IsPointer && pattern.ElementType !.MatchesExactly(actual.GetElementType() !)); } else if (pattern.IsConstructedGenericType) { if (!actual.IsConstructedGenericType) { return(false); } if (!(pattern.GetGenericTypeDefinition() == actual.GetGenericTypeDefinition())) { return(false); } Type[] patternGenericTypeArguments = pattern.GenericTypeArguments; Type[] actualGenericTypeArguments = actual.GenericTypeArguments; int count = patternGenericTypeArguments.Length; if (count != actualGenericTypeArguments.Length) { return(false); } for (int i = 0; i < count; i++) { Type patternGenericTypeArgument = patternGenericTypeArguments[i]; if (patternGenericTypeArgument is SignatureType signatureType) { if (!signatureType.MatchesExactly(actualGenericTypeArguments[i])) { return(false); } } else { if (patternGenericTypeArgument != actualGenericTypeArguments[i]) { return(false); } } } return(true); } else if (pattern.IsGenericMethodParameter) { if (!actual.IsGenericMethodParameter) { return(false); } if (pattern.GenericParameterPosition != actual.GenericParameterPosition) { return(false); } return(true); } else { return(false); } }
private static Type?TryResolve(this SignatureType signatureType, Type[] genericMethodParameters) { if (signatureType.IsSZArray) { return(signatureType.ElementType !.TryResolve(genericMethodParameters)?.TryMakeArrayType()); } else if (signatureType.IsVariableBoundArray) { return(signatureType.ElementType !.TryResolve(genericMethodParameters)?.TryMakeArrayType(signatureType.GetArrayRank())); } else if (signatureType.IsByRef) { return(signatureType.ElementType !.TryResolve(genericMethodParameters)?.TryMakeByRefType()); } else if (signatureType.IsPointer) { return(signatureType.ElementType !.TryResolve(genericMethodParameters)?.TryMakePointerType()); } else if (signatureType.IsConstructedGenericType) { Type[] genericTypeArguments = signatureType.GenericTypeArguments; int count = genericTypeArguments.Length; Type?[] newGenericTypeArguments = new Type[count]; for (int i = 0; i < count; i++) { Type genericTypeArgument = genericTypeArguments[i]; if (genericTypeArgument is SignatureType signatureGenericTypeArgument) { newGenericTypeArguments[i] = signatureGenericTypeArgument.TryResolve(genericMethodParameters); if (newGenericTypeArguments[i] == null) { return(null); } } else { newGenericTypeArguments[i] = genericTypeArgument; } } return(signatureType.GetGenericTypeDefinition().TryMakeGenericType(newGenericTypeArguments !)); } else if (signatureType.IsGenericMethodParameter) { int position = signatureType.GenericParameterPosition; if (position >= genericMethodParameters.Length) { return(null); } return(genericMethodParameters[position]); } else { return(null); } }