/// <summary> /// Returns method as defined on a non-generic base class or on a base /// instantiation. /// For example, If Foo<T> : Bar<T> and overrides method M, /// if method is Bar<string>.M(), then this returns Bar<T>.M() /// but if Foo : Bar<string>, then this returns Bar<string>.M() /// </summary> /// <param name="targetType">A potentially derived type</param> /// <param name="method">A base class's virtual method</param> public static MethodDesc FindMethodOnTypeWithMatchingTypicalMethod(this TypeDesc targetType, MethodDesc method) { // If method is nongeneric and on a nongeneric type, then it is the matching method if (!method.HasInstantiation && !method.OwningType.HasInstantiation) { return(method); } // Since method is an instantiation that may or may not be the same as typeExamine's hierarchy, // find a matching base class on an open type and then work from the instantiation in typeExamine's // hierarchy TypeDesc typicalTypeOfTargetMethod = method.GetTypicalMethodDefinition().OwningType; TypeDesc targetOrBase = targetType; do { TypeDesc openTargetOrBase = targetOrBase; if (openTargetOrBase is InstantiatedType) { openTargetOrBase = openTargetOrBase.GetTypeDefinition(); } if (openTargetOrBase == typicalTypeOfTargetMethod) { // Found an open match. Now find an equivalent method on the original target typeOrBase MethodDesc matchingMethod = targetOrBase.FindMethodOnExactTypeWithMatchingTypicalMethod(method); return(matchingMethod); } targetOrBase = targetOrBase.BaseType; } while (targetOrBase != null); Debug.Fail("method has no related type in the type hierarchy of type"); return(null); }