예제 #1
0
        public NewDelegateExpression(Type delegateType, Expression target, MethodInfo method)
            : base(ArgumentUtility.CheckNotNull("delegateType", delegateType))
        {
            // target may be null for static methods
            ArgumentUtility.CheckNotNull("method", method);
            Assertion.IsNotNull(method.DeclaringType);

            if (!delegateType.IsSubclassOf(typeof(MulticastDelegate)))
            {
                throw new ArgumentException("Delegate type must be subclass of 'System.MulticastDelegate'.", "delegateType");
            }

            if (!method.IsStatic && target == null)
            {
                throw new ArgumentException("Instance method requires target.", "target");
            }

            if (method.IsStatic && target != null)
            {
                throw new ArgumentException("Static method must not have target.", "target");
            }

            if (target != null && !method.DeclaringType.IsTypePipeAssignableFrom(target.Type))
            {
                throw new ArgumentException("Method is not declared on type hierarchy of target.", "method");
            }

            if (!MethodSignature.AreEqual(delegateType.GetMethod("Invoke"), method))
            {
                throw new ArgumentException("Method signature must match delegate type.", "method");
            }

            _target = target;
            _method = method;
        }
예제 #2
0
        /// <inheritdoc />
        public bool IsShadowed(MethodInfo baseDefinition, IEnumerable <MethodInfo> shadowingCandidates)
        {
            ArgumentUtility.CheckNotNull("baseDefinition", baseDefinition);
            ArgumentUtility.CheckNotNull("shadowingCandidates", shadowingCandidates);
            Assertion.DebugAssert(s_memberInfoEqualityComparer.Equals(baseDefinition, MethodBaseDefinitionCache.GetBaseDefinition(baseDefinition)));

            return(shadowingCandidates.Any(
                       m => m.Name == baseDefinition.Name &&
                       MethodSignature.AreEqual(m, baseDefinition) &&
                       baseDefinition.DeclaringType.IsTypePipeAssignableFrom(m.DeclaringType.BaseType) &&
                       !s_memberInfoEqualityComparer.Equals(baseDefinition, MethodBaseDefinitionCache.GetBaseDefinition(m))));
        }
예제 #3
0
        public void IsShadowed_UnrelatedMethod()
        {
            var baseDefinition      = NormalizingMemberInfoFromExpressionUtility.GetMethod((UnrelatedType obj) => obj.UnrelatedMethod());
            var shadowingCandidates = GetDeclaredMethods(typeof(DomainType));

            var unrelatedMethod = shadowingCandidates.Single(m => m.Name == "UnrelatedMethod");

            Assert.That(MethodSignature.AreEqual(baseDefinition, unrelatedMethod), Is.True);

            var result = _finder.IsShadowed(baseDefinition, shadowingCandidates);

            Assert.That(result, Is.False);
        }
예제 #4
0
        /// <summary>
        /// Adds an explicit base definition, i.e., a root <see cref="MethodInfo"/> explicitly overridden by this <see cref="MethodInfo"/>.
        /// </summary>
        /// <param name="overriddenMethodBaseDefinition">The overridden method base definition.</param>
        /// <remarks>
        /// This method does not affect <see cref="GetBaseDefinition"/> or <see cref="BaseMethod"/>, both of which only return implicitly overridden
        /// methods. Methods can override both a single method implicitly and multiple methods explicitly.
        /// </remarks>
        public void AddExplicitBaseDefinition(MethodInfo overriddenMethodBaseDefinition)
        {
            ArgumentUtility.CheckNotNull("overriddenMethodBaseDefinition", overriddenMethodBaseDefinition);

            if (!IsVirtual)
            {
                // TODO 4695: Adapt message
                var message = string.Format("Cannot add an explicit base definition to the non-virtual method '{0}'.", Name);
                throw new NotSupportedException(message);
            }

            if (!overriddenMethodBaseDefinition.IsVirtual || overriddenMethodBaseDefinition.IsFinal)
            {
                throw new ArgumentException("Method must be virtual and non-final.", "overriddenMethodBaseDefinition");
            }

            if (!MethodSignature.AreEqual(this, overriddenMethodBaseDefinition))
            {
                throw new ArgumentException("Method signatures must be equal.", "overriddenMethodBaseDefinition");
            }

            if (!overriddenMethodBaseDefinition.DeclaringType.IsTypePipeAssignableFrom(DeclaringType))
            {
                throw new ArgumentException("The overridden method must be from the same type hierarchy.", "overriddenMethodBaseDefinition");
            }

            if (MethodBaseDefinitionCache.GetBaseDefinition(overriddenMethodBaseDefinition) != overriddenMethodBaseDefinition)
            {
                throw new ArgumentException(
                          "The given method must be a root method definition. (Use GetBaseDefinition to get a root method.)",
                          "overriddenMethodBaseDefinition");
            }

            // TODO: check all mutable methods not just the current one
            if (_addedExplicitBaseDefinitions.Contains(overriddenMethodBaseDefinition))
            {
                throw new InvalidOperationException("The given method has already been added to the list of explicit base definitions.");
            }

            _addedExplicitBaseDefinitions.Add(overriddenMethodBaseDefinition);
            if (ExplicitBaseDefinitionAdded != null)
            {
                ExplicitBaseDefinitionAdded(this, new ExplicitBaseDefinitionsAddedEventArgs(overriddenMethodBaseDefinition));
            }
        }
예제 #5
0
 public void AreEqual()
 {
     Assert.That(MethodSignature.AreEqual(_genericMethod1, _genericMethod2), Is.True);
     Assert.That(MethodSignature.AreEqual(_genericMethod1, _genericMethod3), Is.False);
 }
예제 #6
0
        public MutableEventInfo CreateEvent(
            MutableType declaringType,
            string name,
            EventAttributes attributes,
            MutableMethodInfo addMethod,
            MutableMethodInfo removeMethod,
            MutableMethodInfo raiseMethod)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("addMethod", addMethod);
            ArgumentUtility.CheckNotNull("removeMethod", removeMethod);
            // Raise method may be null.

            MemberAttributesUtility.ValidateAttributes("events", MemberAttributesUtility.InvalidEventAttributes, attributes, "attributes");

            if (addMethod.IsStatic != removeMethod.IsStatic || (raiseMethod != null && raiseMethod.IsStatic != addMethod.IsStatic))
            {
                throw new ArgumentException("Accessor methods must be all either static or non-static.", "addMethod");
            }

            if (!ReferenceEquals(addMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Add method is not declared on the current type.", "addMethod");
            }
            if (!ReferenceEquals(removeMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Remove method is not declared on the current type.", "removeMethod");
            }
            if (raiseMethod != null && !ReferenceEquals(raiseMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Raise method is not declared on the current type.", "raiseMethod");
            }

            if (addMethod.ReturnType != typeof(void))
            {
                throw new ArgumentException("Add method must have return type void.", "addMethod");
            }
            if (removeMethod.ReturnType != typeof(void))
            {
                throw new ArgumentException("Remove method must have return type void.", "removeMethod");
            }

            var addMethodParameterTypes    = addMethod.GetParameters().Select(p => p.ParameterType).ToList();
            var removeMethodParameterTypes = removeMethod.GetParameters().Select(p => p.ParameterType).ToList();

            if (addMethodParameterTypes.Count != 1 || !addMethodParameterTypes[0].IsSubclassOf(typeof(Delegate)))
            {
                throw new ArgumentException("Add method must have a single parameter that is assignable to 'System.Delegate'.", "addMethod");
            }
            if (removeMethodParameterTypes.Count != 1 || !removeMethodParameterTypes[0].IsSubclassOf(typeof(Delegate)))
            {
                throw new ArgumentException("Remove method must have a single parameter that is assignable to 'System.Delegate'.", "removeMethod");
            }

            if (addMethodParameterTypes.Single() != removeMethodParameterTypes.Single())
            {
                throw new ArgumentException("The type of the handler parameter is different for the add and remove method.", "removeMethod");
            }

            var handlerType  = addMethodParameterTypes.Single();
            var invokeMethod = GetInvokeMethod(handlerType);

            if (raiseMethod != null && !MethodSignature.AreEqual(raiseMethod, invokeMethod))
            {
                throw new ArgumentException("The signature of the raise method does not match the handler type.", "raiseMethod");
            }

            var signature = new EventSignature(handlerType);

            if (declaringType.AddedEvents.Any(e => e.Name == name && EventSignature.Create(e).Equals(signature)))
            {
                throw new InvalidOperationException("Event with equal name and signature already exists.");
            }

            return(new MutableEventInfo(declaringType, name, attributes, addMethod, removeMethod, raiseMethod));
        }