Open sandboxFocusImprove this doc

PS0120: Multicast Pointcut Selects Declarations with Unsupported Attributes

Severity Error
Reported by PostSharp
Message Invalid MulticastPointcut attribute on the advice "<Advice>": this kind of advice cannot apply to declarations with the attribute(s) "<Attributes>".

Cause

A MulticastPointcut selects the declarations to which an advice of a composite aspect applies. Its Attributes property filters these declarations by visibility, scope, virtuality, abstraction and other characteristics. Each kind of advice supports only some of these values. For example, the advices of methods (OnMethodEntryAdvice, OnMethodInvokeAdvice...) and of locations cannot apply to abstract members, which have no body, and the advices of locations cannot apply to literal fields (constants).

PostSharp reports PS0120, on the advice method <Advice>, when Attributes contains a value that the advice does not support. <Attributes> lists these values, as MulticastAttributes flags.

In the following example, an OnMethodEntryAdvice selects methods with AnyAbstraction, which includes abstract methods.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;
using PostSharp.Serialization;

namespace Errors.PS0120_Error;

// Logs the entry into the public methods of the target class.
[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // An abstract method has no body, so an OnMethodEntry advice cannot apply to it.
    [OnMethodEntryAdvice, MulticastPointcut( Targets = MulticastTargets.Method, Attributes = MulticastAttributes.Public | MulticastAttributes.AnyAbstraction )]
    public void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
}

[LogMethods]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order for {product} placed." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Chair" );
    }
}
error PS0120: PS0120_Error.cs(15,17): Invalid MulticastPointcut attribute on the advice "Errors.PS0120_Error.LogMethodsAttribute.OnEntry(PostSharp.Aspects.MethodExecutionArgs)": this kind of advice cannot apply to declarations with the attribute(s) "Abstract".

Resolution

  • Remove the unsupported values from Attributes, for example replace AnyAbstraction with NonAbstract.
  • Otherwise, do not set the abstraction or literality category of Attributes: PostSharp then uses the values that the advice supports for every category that you leave unset.

In the following example, the pointcut selects only non-abstract public methods.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;
using PostSharp.Serialization;

namespace Errors.PS0120_Fixed;

// Logs the entry into the public methods of the target class.
[PSerializable]
public class LogMethodsAttribute : TypeLevelAspect
{
    // The pointcut selects only methods that have a body.
    [OnMethodEntryAdvice, MulticastPointcut( Targets = MulticastTargets.Method, Attributes = MulticastAttributes.Public | MulticastAttributes.NonAbstract )]
    public void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
}

[LogMethods]
public class OrderService
{
    public void PlaceOrder( string product ) => Console.WriteLine( $"Order for {product} placed." );
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Chair" );
    }
}
Entering PlaceOrder.
Order for Chair placed.

See Also

Reference

MulticastPointcut
MulticastAttributes

Other Resources

Selecting Members with Pointcuts
Advice Methods