Open sandboxFocusImprove this doc

Advice Parameters

An advice method receives the values that it needs from the target as parameters. Each parameter has a custom attribute, called a binding attribute, that selects the value: an argument, the instance, the return value, the exception, a variable shared by several advices, or a field, property or method of the target type. This mechanism is called advice parameter binding.

Bound parameters have the following benefits over a single AdviceArgs parameter, such as MethodExecutionArgs:

  • The woven code computes only the values that the advice declares. No AdviceArgs object is allocated on each call.
  • The parameters are typed. An argument of a value type is not boxed when the parameter has the type of the argument or is generic.
  • PostSharp checks the signature of the advice when it builds the aspect, and again for each target. An advice that does not fit a target causes a build error instead of an exception at run time.

The binding attributes derive from AdviceParameterAttribute and are in the PostSharp.Aspects.Advices namespace, except ImportMemberAttribute, which is also used on the fields of an aspect (see Accessing Members of the Target Class). For an introduction to advices and pointcuts, see Advice Methods. To convert an existing aspect, see Modernizing Your Custom Aspects.

Example

The following aspect measures the duration of a method and writes it to the console with the value of the first argument. The entry advice starts a Stopwatch and stores it in a variable bound by StateAttribute. The advices have no pointcut, so they apply to the target method of the aspect and form one group (see How it works). The stopwatch parameter of the exit advice is therefore bound to the same variable.

[PSerializable]
public sealed class StopwatchAttribute : MethodLevelAspect
{
    [OnMethodEntryAdvice]
    public void OnEntry( [State( StateScope.MethodInvocation )] out Stopwatch stopwatch )
    {
        stopwatch = Stopwatch.StartNew();
    }

    [OnMethodExitAdvice]
    public void OnExit( [DeclarationName] string methodName,
                        [Argument( 0 )] object argument,
                        [State( StateScope.MethodInvocation )] Stopwatch stopwatch )
    {
        Console.WriteLine( "{0}({1}) took {2} ms.", methodName, argument, stopwatch.ElapsedMilliseconds );
    }
}

Rules of an advice signature

An advice method with bound parameters follows these rules:

  • The method is public. It can be static or an instance method, and it returns void.
  • Each parameter has exactly one binding attribute.
  • Only the first parameter can have no binding attribute. It must then be of the AdviceArgs type of the advice, for instance MethodExecutionArgs in a method boundary advice. The other parameters are bound as usual. An AdviceArgs parameter is an obsolete practice, supported for compatibility with existing aspects. Prefer bound parameters (see Modernizing Your Custom Aspects). OnInstanceConstructedAdvice accepts no AdviceArgs parameter.
  • A parameter can be passed by value, or as in, ref or out. Each binding attribute accepts some of these modes. A ref or out parameter gives write access to the bound value, for instance to replace an argument or the return value.
  • The type of a parameter passed by value can be the type of the bound value, or a base type of it when the value is of a reference type. With [Argument], [ReturnValue] and [This], a parameter of a reference type, such as object, receives a boxed copy of a value of a value type. The other bindings require the types listed in the table below. A parameter passed as in, ref or out must have exactly the type of the bound value.
  • The method can be generic. The type arguments are then inferred for each target. See Generic advice methods.

Only the binding attributes of PostSharp are supported. A custom attribute that you derive from AdviceParameterAttribute causes an error.

Binding attributes

The following table lists the binding attributes, the value they bind and the parameter modes they accept. The documentation of each attribute gives the details.

Attribute Bound value Parameter type Modes
ArgumentAttribute An argument of the target method, selected by its index, its name or its type. The type of the argument, or a base type. Any. With ref or out, the method body and the next advices see the changes.
ArgumentsAttribute All the arguments, in a new Arguments object allocated on each call. Arguments or object. By value.
ThisAttribute The instance of the target (this). null or the default value on a static target, unless IsRequired is true. The type of the instance, or a base type. By value. ref or in only on a struct.
StateAttribute A variable shared by the advices of a group for one execution of the target method. Its initial value is the default value of its type. Any type, the same in all the advices that bind the slot. Any.
ReturnValueAttribute The return value of the target method. In a method boundary advice applied semantically to an async method, the result of the task. The return type. Depends on the advice. See Reading and setting the return value.
ExceptionAttribute The exception thrown by the target method. Exception, or object by value. Any. With ref or out, the advice can replace the exception.
FlowBehaviorAttribute A FlowBehavior variable that the advice sets to change the control flow. FlowBehavior. ref or out.
AwaiterAttribute An awaiter that the async method awaits after the advice, with FlowBehavior.Yield. A type that implements INotifyCompletion. ref or out.
AwaitedTaskAttribute The task that the async method awaits. Task, IAsyncResult or object. By value.
AwaitedMethodAttribute The method that the async method called to get the awaited object. MethodBase, MemberInfo or object. By value.
CurrentTaskAttribute The task that the caller of the async method observes. null until the method yields. Task, IAsyncResult or object. By value.
AsyncCallIdAttribute The AsyncCallId that identifies the current execution of the async method. AsyncCallId. By value.
DeclarationAttribute The reflection object of the target: MethodBase, LocationInfo or Type, depending on the advice. It is not looked up on each call, except for generic targets. The type of the reflection object, or a base type. By value.
DeclarationIdentifierAttribute The DeclarationIdentifier of the target. DeclarationIdentifier. By value.
DeclarationNameAttribute The name of the target, which is a constant. With IncludeTypeName, the name is prefixed with the full name of the declaring type. string. By value.
LocationValueAttribute The value of the field or property. The type of the field or property. out or ref in a get advice. Any in a set advice.
BindingAttribute The binding object, which invokes the next node in the chain of interceptions of the target. IMethodBinding in a method interception advice. ILocationBinding<T> or ILocationBinding in a location advice. By value.
ImportMemberAttribute A field, a property or a method of the target type, selected by its name or by its type. See Importing members of the target type. The type of the field or property, ILocationBinding<T>, ILocationBinding, a delegate type, IMethodBinding, Property<TValue> or Event<TDelegate>. Any for a field. By value or in for a property. By value for the other types.

Bindings by advice kind

The following advices accept bound parameters:

The other advices, such as the event interception advices, LocationValidationAdvice and OnInstanceLocationInitializedAdvice, do not accept them. A binding attribute on one of their parameters causes the error LA0209 in OnInstanceLocationInitializedAdvice, and in OnMethodInvokeAsyncAdvice for the bindings other than [This] and [ImportMember], and for any binding in a generic method, and the error LA0085 in the event interception advices and LocationValidationAdvice, whose signature is fixed.

The following table shows which binding attributes each advice accepts. In the column headings, Entry, Success, Exception, Exit, Yield and Resume are the method boundary advices, Invoke is OnMethodInvokeAdvice, Location is the location interception advices, and Constructed is OnInstanceConstructedAdvice. Yes means that the attribute is accepted with the modes of the previous table. out, ref means that only these modes are accepted in this advice.

Attribute Entry Success Exception Exit Yield Resume Invoke Location Constructed
[Argument] Yes Yes Yes Yes Yes Yes Yes
[Arguments] Yes Yes Yes Yes Yes Yes Yes
[This] Yes Yes Yes Yes Yes Yes Yes Yes Yes
[State] Yes Yes Yes Yes Yes Yes Yes Yes Yes
[ReturnValue] out, ref Yes out, ref Yes out, ref
[Exception] Yes
[FlowBehavior] Yes Yes Yes
[Awaiter] Yes Yes
[AwaitedTask], [AwaitedMethod] Yes
[CurrentTask], [AsyncCallId] Yes Yes Yes Yes Yes Yes
[Declaration], [DeclarationIdentifier], [DeclarationName] Yes Yes Yes Yes Yes Yes Yes Yes Yes
[LocationValue] Yes
[Binding] Yes Yes
[ImportMember] Yes Yes Yes Yes Yes Yes Yes Yes Yes

A binding attribute in an advice that does not accept it causes the error LA0151. In OnInstanceConstructedAdvice, [Argument], [ReturnValue], [LocationValue] and [FlowBehavior] cause the error LA0224 instead. In the other advices, [Arguments] and [FlowBehavior] cause the warning LA0233, because the code builds but the value is ignored or not defined.

An advice can have at most one [ReturnValue] parameter and one [Exception] parameter. When an advice has several [FlowBehavior] parameters, only the last one is read, and PostSharp reports the warning LA0236. Several [Awaiter] parameters share one variable, and also cause the warning LA0236. The other attributes can be used several times in one advice, for instance to bind two arguments.

Common scenarios

Sharing state between advices

A parameter annotated with StateAttribute is bound to a variable that lives for one execution of the target method. Each execution has its own variable, and its initial value is the default value of its type.

Each variable is identified by a name, called a slot. The slot is the name of the parameter, or the second argument of the StateAttribute constructor. The advices of one group that bind the same slot share the variable, and all their parameters bound to this slot must have the same type. Advices of different groups, or of different aspects, never share a variable.

An out or ref parameter writes the variable. A parameter passed by value or as in reads it. In an async method or an iterator, the variable is a field of the state machine, so it keeps its value across await and yield return statements.

The only scope is StateScope.MethodInvocation. To keep a value for the lifetime of an object, use a field of an instance-scoped aspect (see Understanding Aspect Lifetime and Scope).

Reading and setting the return value

The meaning of a parameter annotated with ReturnValueAttribute depends on the advice:

In a method boundary advice applied semantically to an async method, or to a non-async method that returns a task, the return value is the result of the task (see Semantic Advising of Iterator and Async Methods). When SemanticallyAdvisedMethodKinds disables semantic advising, and in an OnMethodInvokeAdvice, the return value is the task or the enumerable itself. In a method boundary advice applied semantically, when the target method has no return value that the advice can access (it returns void, a task without a result or a reference, or it is an iterator), the parameter receives the default value, and a value written to it is ignored. Set IsRequired to true to report an error instead.

The following aspect returns a cached value from the entry advice, and stores the value that the method returns in the success advice. The advices are generic, so the value is not boxed. IsRequired makes the build fail on a method that returns no value, to which the aspect does not apply. Cache<T> is a class of your application.

[PSerializable]
public sealed class CacheAttribute : MethodLevelAspect
{
    [OnMethodEntryAdvice]
    public static void OnEntry<T>( [Argument( 0 )] string key,
                                   [ReturnValue( IsRequired = true )] out T returnValue,
                                   [FlowBehavior] out FlowBehavior flowBehavior )
    {
        if ( Cache<T>.TryGetValue( key, out returnValue ) )
        {
            flowBehavior = FlowBehavior.Return;
        }
        else
        {
            flowBehavior = FlowBehavior.Default;
        }
    }

    [OnMethodSuccessAdvice]
    public static void OnSuccess<T>( [Argument( 0 )] string key, [ReturnValue] T returnValue )
    {
        Cache<T>.Set( key, returnValue );
    }
}

When the aspect is applied to a GetStock method, calling the method twice with the same argument executes it only once:

Querying the stock of P001.
Stock: 12
Stock: 12

On an async method, the entry advice of this aspect causes the warning LA0154, because it has a [FlowBehavior] parameter but no [Awaiter] parameter.

Handling exceptions

In OnMethodExceptionAdvice, a parameter annotated with ExceptionAttribute receives the exception thrown by the target method. With a ref or out parameter, the advice can replace the exception. The FlowBehavior value set through a [FlowBehavior] parameter decides what happens next:

FlowBehavior.ThrowException throws the exception with a throw instruction, not a rethrow instruction, so the stack trace of the original exception is replaced.

The following advice wraps every exception into a DataAccessException:

[OnMethodExceptionAdvice]
public static void OnException( [DeclarationName] string methodName,
                                [Exception] ref Exception exception,
                                [FlowBehavior] out FlowBehavior flowBehavior )
{
    exception = new DataAccessException( $"{methodName} failed.", exception );
    flowBehavior = FlowBehavior.ThrowException;
}

The [Exception] binding is not available in OnMethodExitAdvice.

Intercepting methods

In OnMethodInvokeAdvice, the advice calls the intercepted method through the IMethodBinding received by a [Binding] parameter. The Invoke method takes the instance and an Arguments object, which a [Arguments] parameter provides. The following aspect calls the method again, up to three times, when the method throws an IOException. For each target method, T is the return type of the method.

[PSerializable]
public sealed class RetryAttribute : MethodLevelAspect
{
    [OnMethodInvokeAdvice]
    public static void OnInvoke<T>( [This] object instance,
                                    [Binding] IMethodBinding binding,
                                    [Arguments] Arguments arguments,
                                    [ReturnValue] out T returnValue )
    {
        for ( int attempt = 1; ; attempt++ )
        {
            try
            {
                returnValue = (T) binding.Invoke( ref instance, arguments );
                return;
            }
            catch ( IOException ) when ( attempt < 3 )
            {
            }
        }
    }
}

When the aspect is applied to a method that fails twice with an IOException, the third call succeeds:

Reading greeting.txt, attempt 1.
Reading greeting.txt, attempt 2.
Reading greeting.txt, attempt 3.
Hello, world.

Apply this aspect only to methods that return a value and that are not async. An exception thrown after the first await of an async method is stored in the returned task, so this advice does not retry it.

An [Argument] parameter passed as ref or out in an interception advice does not change the argument that the intercepted method receives, and PostSharp reports the warning LA0235. To change an argument, change it in the Arguments object passed to the binding.

Intercepting fields and properties

In OnLocationGetValueAdvice and OnLocationSetValueAdvice, a [Binding] parameter receives the ILocationBinding<T> of the field or property, which gets or sets the underlying value. A [LocationValue] parameter is the value:

  • In a get advice, the parameter is out or ref, and the advice assigns the value that the getter returns. A get advice must have either a [LocationValue] parameter or a LocationInterceptionArgs parameter (error LA0237).
  • In a set advice, the parameter receives the value assigned to the field or property. The advice stores it by calling the binding.

On an instance field or property of a struct, the instance parameter receives a boxed copy, so the value is stored in the copy and lost. Apply such an aspect only to classes and static members, or keep the LocationInterceptionArgs signature for structs.

In a get advice, a [LocationValue] parameter passed by value compiles, but the getter then returns the default value.

[PSerializable]
public sealed class TrimAttribute : LocationLevelAspect
{
    [OnLocationGetValueAdvice]
    public static void OnGetValue( [This] object instance,
                                   [Binding] ILocationBinding<string> binding,
                                   [LocationValue] out string value )
    {
        value = binding.GetValue( instance );
    }

    [OnLocationSetValueAdvice]
    public static void OnSetValue( [This] object instance,
                                   [Binding] ILocationBinding<string> binding,
                                   [LocationValue] string value )
    {
        binding.SetValue( instance, value?.Trim() );
    }
}

Importing members of the target type

A parameter annotated with ImportMemberAttribute receives a field, a property or a method of the target type. The target type is the type to which the aspect is applied, or the type that declares the member to which it is applied. The aspect can be of any kind, including a statically scoped aspect such as a MethodLevelAspect. An aspect field annotated with ImportMemberAttribute requires an InstanceLevelAspect (see Accessing Members of the Target Class), but an advice parameter does not.

The type and the mode of the parameter select what the advice receives:

  • A parameter of the type of a field receives the field. By value or as in, it reads a copy of the value. As ref or out, it receives a reference to the field, so the advice can change the field. A ref or out parameter requires a field that is not read-only, or a property that returns a reference that is not read-only.
  • A parameter of the type of a property, by value or as in, receives the value that the getter returns when the advice is called.
  • A parameter of type ILocationBinding<T> or ILocationBinding receives an object that reads and writes the field or property on the instance passed to its methods, typically received by a [This] parameter. There is one binding object per member and target type.
  • A parameter of a delegate type, with a member name, receives an open delegate of a method. For an instance method, the first parameter of the delegate receives the instance, and the other parameters receive the arguments. The delegate type selects the overload, as when C# converts a method group to a delegate, and a virtual method is called with virtual dispatch. The delegate is created once per target type, so calling it does not allocate. For a struct, see the note below.
  • A parameter of type IMethodBinding, with a member name, receives an object that calls the method on the instance passed to Invoke, with the arguments of an Arguments object. It selects the method by its name only, so a method that has overloads must be imported as a delegate. The method must not be generic, and must not return by reference.
  • A parameter of type IEventBinding, with a member name, receives an object that adds and removes handlers of the event on the instance passed to its methods.
  • In an instance advice of an instance-scoped aspect (see Understanding Aspect Lifetime and Scope), a parameter of type Property<TValue> or Event<TDelegate>, with a member name, receives delegates bound to the target object, as an aspect field of these types does.

When the attribute has several member names, PostSharp tries them in order, and selects the first member whose kind and type the parameter accepts. Without a name, it selects a field or a property by its type, as [Argument] selects an argument: a parameter passed by value accepts a member whose type can be assigned to it without a conversion other than boxing, and a parameter passed by reference, or a location binding, requires exactly the type of the member. When several members match, the build fails, and you must specify the name. A method is always selected by its name.

Note

To import a method of a struct as a delegate, declare a delegate type of your own: its first parameter must be in, or ref for a method that is not readonly.

The candidates are the members of the target type and the accessible members of its base types, nearest first. Indexers, constants and the fields generated by the compiler are not candidates. The members introduced with IntroduceMemberAttribute are not candidates either, because PostSharp selects the member before the introductions. The fields that the aspect requests with IntroduceFieldAdviceInstance are candidates, and they win over the other members (see Requesting fields).

When no member matches, a parameter passed by value receives null or the default value, and a ref or out parameter receives a reference to a temporary variable. Set IsRequired to true to make the build fail instead. On a static target, a parameter passed by value receives the default value of an instance member, and a parameter passed by reference to an instance field causes an error.

The following aspect is a MethodLevelAspect, which is statically scoped. Its advice increments the callCount field of the target object through a ref parameter, reads the Name property, and calls the private OnCalled method through an open delegate. The advice is generic: T is the type of the target object, and the delegate type Action<T, int> selects the method OnCalled( int ).

[PSerializable]
public sealed class CountCallsAttribute : MethodLevelAspect
{
    [OnMethodEntryAdvice]
    public static void OnEntry<T>( [This] T instance,
                                   [ImportMember( "callCount", IsRequired = true )] ref int callCount,
                                   [ImportMember( "Name" )] string name,
                                   [ImportMember( "OnCalled" )] Action<T, int> onCalled )
    {
        callCount++;
        Console.WriteLine( "{0}: call {1}.", name, callCount );
        onCalled?.Invoke( instance, callCount );
    }
}

The aspect is applied to the Print method of the following class:

public class Printer
{
    private int callCount;

    public Printer( string name )
    {
        this.Name = name;
    }

    public string Name { get; }

    public int CallCount => this.callCount;

    public void ResetCallCount() => this.callCount = 0;

    [CountCalls]
    public void Print( string text ) => Console.WriteLine( "Printing '{0}'.", text );

    private void OnCalled( int count )
    {
        if ( count > 1 )
        {
            Console.WriteLine( "{0} has been called {1} times.", this.Name, count );
        }
    }
}

Each object has its own counter, which the class can also read and reset:

Printer A: call 1.
Printing 'first'.
Printer A: call 2.
Printer A has been called 2 times.
Printing 'second'.
CallCount = 2
Printer A: call 1.
Printing 'third'.
Printer B: call 1.
Printing 'fourth'.

When another aspect turns the imported field into a property, for instance a LocationInterceptionAspect, the order of the two aspects decides what the parameter receives. An aspect ordered before the other one receives the field itself. An aspect ordered after it receives the property: the values go through the accessors, and a ref or out parameter causes an error. Order the aspects with aspect dependencies (see Coping with Several Aspects on the Same Target).

For a method, a property or an event imported as a delegate, an IMethodBinding, a Property<TValue> or an Event<TDelegate>, Order has the meaning that it has on an aspect field. With ImportMemberOrder.BeforeIntroductions, the parameter calls the method as it was before the aspect introduced or overrode it, without virtual dispatch.

Async methods

The method boundary advices of an async method can use the following bindings:

  • [AsyncCallId] gives an identifier that is the same in all the advices of one execution of the method. It can correlate log records. On a method that is not async, the parameter receives the default value, unless IsRequired is true (error LA0219).
  • [CurrentTask] gives the task that the caller observes. The task exists only once the method has yielded, so the parameter is null in the entry advice, in the first yield advice, and in all the advices of an execution that completes without yielding. It is always null in a method that is not async, in a method implemented with runtime async (warning LA0240), and with a method builder other than the default builders of Task and ValueTask.
  • [AwaitedTask] and [AwaitedMethod] give, in the yield advice, the task that the method awaits and the method that returned it.
  • [Awaiter] and [FlowBehavior], in the entry and resume advices, make the method await an awaiter of the aspect before it continues. The advice assigns the awaiter and sets the flow behavior to FlowBehavior.Yield. PostSharp Threading uses this mechanism to switch to another thread.

The [State] variables, the ref [Argument] parameters and the [This] instance of a struct are fields of the state machine, so the advices see the same values before and after an await.

Mixing AdviceArgs and bound parameters

When an advice has both a MethodExecutionArgs parameter and a bound parameter that sets the same value, the bound parameter takes precedence, and PostSharp reports a warning:

Generic advice methods

An advice method can be generic. For each target, PostSharp infers the type arguments from the values bound by [Argument], [Arguments], [Binding], [LocationValue], [ReturnValue] and [This], with rules similar to the type inference of C#:

  • A value of a value type is passed without boxing, and a ref, out or in parameter receives the location itself. In both cases, the type argument is exactly the type of the value.
  • Otherwise, the value gives a lower bound. With several lower bounds, the type argument is the type to which all the values can be assigned. For instance, OnEntry<T>( [Argument( 0 )] T a, [Argument( 1 )] T b ) applied to M( string, object ) gives object.
  • The type of the parameter can be a constructed type, such as T[], T? or IList<T>. PostSharp then matches it with the type of the value, its base types and its interfaces.
  • The constraints of the type parameters are checked with the inferred type arguments, including unmanaged, new() and constraints that refer to other type parameters.

When a type argument cannot be inferred, or when it violates a constraint, PostSharp reports the error LA0220, which gives the reason. A type parameter that no bound parameter uses is replaced by object, and PostSharp reports the warning LA0245.

The type of a parameter can also use the type parameters of a generic aspect class. They are replaced by the type arguments of the aspect instance.

Selecting overloads with MatchPointcut

By default, an advice that does not fit a target causes an error. In a type-level aspect, the MatchPointcut pointcut skips these targets instead, so that several advices can handle the overloads of one method. See Match pointcut.

Limitations

The current version of advice parameter binding has the following limitations:

  • A method interception advice cannot call the intercepted method, or read all the arguments, without an Arguments object, which [Arguments] allocates on each call.
  • The event interception advices, LocationValidationAdvice and OnInstanceLocationInitializedAdvice do not accept bound parameters. OnMethodInvokeAsyncAdvice accepts only [This] and [ImportMember], by value, in a method that is not generic.
  • There is no binding for the value yielded by an iterator, which YieldValue gives. FlowBehavior.Yield works only in the entry and resume advices of async methods.
  • A [State] variable lives for one execution of the target method. There is no scope for an instance, a type or the application domain.

Build messages

PostSharp checks the bound parameters when it builds the aspect, and again for each target. It reports all the errors of an aspect in one build. The following table lists the messages.

Code Severity Meaning
LA0085 Error The advice has a fixed signature, such as an event interception advice or LocationValidationAdvice, and does not accept bound parameters.
LA0151 Error The binding attribute cannot be used in this advice.
LA0152 Error The [Awaiter] parameter does not implement INotifyCompletion, or is not passed by reference.
LA0153 Error Two advices of one group have [Awaiter] parameters of different types.
LA0154 Warning An entry or resume advice of an async method has a [FlowBehavior] parameter but no [Awaiter] parameter, so it cannot use FlowBehavior.Yield.
LA0155 Error The [FlowBehavior] parameter is not of type FlowBehavior, or is not passed by reference.
LA0189 Error An out or ref [Argument] parameter is bound to an in argument. Use an in parameter.
LA0207 Error A parameter has more than one binding attribute.
LA0208 Error A parameter other than the first one has no binding attribute.
LA0209 Error The advice does not accept bound parameters.
LA0210 Error The binding attribute is not defined by PostSharp.
LA0211 Error The type of the parameter cannot receive the bound value.
LA0212 Error The parameter must be passed by reference (out or ref).
LA0213 Error The parameter cannot be passed by reference.
LA0214 Error The advice has two parameters with the same binding attribute, which allows only one.
LA0215 Error Two parameters bound to the same [State] slot have different types.
LA0216 Error The index of an [Argument] is negative.
LA0217 Error The type of the parameter is not compatible with the value bound on this target.
LA0218 Error [This] has IsRequired set to true, but the target is static.
LA0219 Error [AsyncCallId] has IsRequired set to true, but the target is not an async method.
LA0220 Error A type argument of the generic advice cannot be inferred for this target.
LA0221 Error A method interception advice is applied to a method that returns a value, but it has neither a [ReturnValue] nor a MethodInterceptionArgs parameter.
LA0222 Error The address of an argument bound by reference cannot be loaded in this advice.
LA0223 Error [This] is passed by reference, but the target type is not a struct.
LA0224 Error [Argument], [ReturnValue], [LocationValue] or [FlowBehavior] is used in OnInstanceConstructedAdvice.
LA0225 Error The target method has no parameter at the index of the [Argument].
LA0226 Error The target method has no parameter with the name of the [Argument].
LA0227 Error The target method has no parameter of the type of the [Argument].
LA0228 Error Several parameters of the target method have the type of the [Argument]. Select the argument by its index or name, or set AmbiguityResolution.
LA0229 Error The parameter must have exactly the type of the bound value, for instance string for [DeclarationName].
LA0233 Warning The binding attribute is not supported in this advice, so the value of the parameter is ignored or not defined.
LA0234 Warning The [FlowBehavior] parameter takes precedence over FlowBehavior.
LA0235 Warning A value written to an out or ref [Argument] of an interception advice does not reach the intercepted method.
LA0236 Warning The advice has several [FlowBehavior] or [Awaiter] parameters.
LA0237 Error A get advice has neither a [LocationValue] nor a LocationInterceptionArgs parameter.
LA0238 Error [AwaitedTask] or [AwaitedMethod] is used on a target that is not an async method.
LA0239 Error [CurrentTask] has IsRequired set to true, but the target cannot provide its task.
LA0240 Warning [CurrentTask] is always null because the C# compiler implemented the method with runtime async.
LA0241 Error [ReturnValue] has IsRequired set to true, but the target has no return value that the advice can access.
LA0242 Error [CurrentTask] has IsRequired set to true in an advice that can run before the method yields.
LA0243 Warning The out or ref [ReturnValue] parameter takes precedence over ReturnValue.
LA0244 Error [CurrentTask] has IsRequired set to true, but the entry advice of the group has an [Awaiter] parameter.
LA0245 Warning A type parameter of the generic advice is not used by any bound parameter, so its type argument is object.
LA0246 Error The type of a [Declaration] parameter cannot receive the reflection object of this kind of advice.
LA0247 Error The [Exception] parameter is not of type Exception, or of type object by value.
LA0248 Warning The out or ref [Exception] parameter takes precedence over Exception.
LA0260 Error An [ImportMember] parameter without a name has IsRequired set to true, but no field or property of the target type has a type that the parameter can receive.
LA0261 Error An [ImportMember] parameter is passed as out or ref to a field that an aspect ordered before it turns into a property.
LA0262 Error An [ImportMember] parameter is passed as out or ref to a field of a struct in an async method or an iterator, which works on a copy of the struct.
LA0263 Error An [ImportMember] delegate parameter has IsRequired set to true, but no method of the name converts to the delegate type.
LA0264 Error Several methods of the name convert to the delegate type of an [ImportMember] parameter.
LA0265 Error An [ImportMember] parameter of type IMethodBinding has IsRequired set to true, but the target type has no method of the name that is not generic and does not return by reference.
LA0266 Error An [ImportMember] parameter of type IMethodBinding names a method that has several overloads. Import the method as a delegate.
LA0267 Error An [ImportMember] parameter of type Property<TValue> or Event<TDelegate> is not in an instance advice of an instance-scoped aspect.
LA0277 Error The delegate type of an [ImportMember] parameter passes a struct as ref to a readonly method. Declare the first parameter of the delegate type as in.
LA0280 Error The type of an [ImportMember] parameter is not supported: Property<TValue, TIndex>.
LA0281 Error An [ImportMember] parameter with a name has IsRequired set to true, but the target type has no accessible field or property of this name that the parameter can receive.
LA0282 Error An [ImportMember] parameter is passed by reference to an instance field, but the target is static.
LA0283 Error An [ImportMember] parameter without a name matches several members of the target type. Specify the name.
LA0284 Error An [ImportMember] parameter of this type, such as ILocationBinding, imports a member by name only. Specify the name.

To suppress a warning, see Ignoring and Escalating Warnings.

See Also

Reference

AdviceParameterAttribute
ImportMemberAttribute
StateAttribute
FlowBehavior

Other Resources

Developing Member-Level Aspects
Advice Methods
Selecting Members with Pointcuts
Accessing Members of the Target Class
Providing Advices Dynamically
Modernizing Your Custom Aspects
Ordering Advices
Semantic Advising of Iterator and Async Methods