Ejemplo n.º 1
0
        public MutableMethodInfo GetOrCreateOverride(MutableType declaringType, MethodInfo overriddenMethod, out bool isNewlyCreated)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNull("overriddenMethod", overriddenMethod);
            Assertion.IsNotNull(overriddenMethod.DeclaringType);

            if (!overriddenMethod.IsVirtual)
            {
                throw new ArgumentException("Only virtual methods can be overridden.", "overriddenMethod");
            }

            CheckIsNotMethodInstantiation(overriddenMethod, "overriddenMethod");

            if (!declaringType.IsSubclassOf(overriddenMethod.DeclaringType))
            {
                var message = string.Format("Method is declared by type '{0}' outside of the proxy base class hierarchy.", overriddenMethod.DeclaringType.Name);
                throw new ArgumentException(message, "overriddenMethod");
            }

            var baseDefinition          = MethodBaseDefinitionCache.GetBaseDefinition(overriddenMethod);
            var existingMutableOverride = _relatedMethodFinder.GetOverride(baseDefinition, declaringType.AddedMethods);

            if (existingMutableOverride != null)
            {
                isNewlyCreated = false;
                return(existingMutableOverride);
            }
            isNewlyCreated = true;

            var baseMethod   = _relatedMethodFinder.GetMostDerivedOverride(baseDefinition, declaringType.BaseType);
            var bodyProvider = CreateBodyProvider(baseMethod);

            var needsExplicitOverride = _relatedMethodFinder.IsShadowed(baseDefinition, declaringType.GetAllMethods());

            if (needsExplicitOverride)
            {
                return(PrivateCreateExplicitOverrideAllowAbstract(declaringType, baseDefinition, bodyProvider));
            }

            var attributes = MethodOverrideUtility.GetAttributesForImplicitOverride(baseMethod);

            return(CreateMethod(declaringType, baseMethod, baseMethod.Name, attributes, bodyProvider));
        }