| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply the advice "<Advice>" to method "<Method>": OnMethodBoundary semantic advising currently can be applied only to iterator and enumerable methods, async methods and any methods returning Task, Task<T>, IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T> without by-reference parameters. You can suppress this error message by setting the UnsupportedTargetAction property on the master advice. |
Cause
This is the counterpart of LA0174 for aspects made of advices, such as OnMethodEntryAdvice and OnMethodExitAdvice. By default, a group of method boundary advices advises semantically the methods that return an awaitable type, also when they are not async. For such a method, which has no state machine, PostSharp generates one. It can do so only for a method that returns a Task, a Task<TResult> or an enumerable type, and has no ref or out parameter.
PostSharp reports LA0175 on the target method when it should advise the method semantically, cannot generate the state machine, and the UnsupportedTargetAction property of the master advice of the group keeps its default value, Fail. The typical case is a method that returns a ValueTask<TResult> without the async keyword. <Advice> is the master advice.
In the following example, the advices of the [Log] aspect are applied to a method that returns a ValueTask<decimal> and is not async.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0175_Error;
[PSerializable]
public class LogAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
[OnMethodExitAdvice]
public void OnExit( MethodExecutionArgs args ) => Console.WriteLine( $"Leaving {args.Method.Name}." );
}
public class PriceService
{
// The method returns a ValueTask<T> but is not async, so PostSharp cannot advise the task semantically.
[Log]
public ValueTask<decimal> GetPriceAsync( string product )
{
return new ValueTask<decimal>( product.Length * 1.5m );
}
}
public static class Program
{
public static async Task Main()
{
Console.WriteLine( await new PriceService().GetPriceAsync( "Coffee" ) );
}
}
error LA0175: LA0175_Error.cs(23,31): Cannot apply the advice "Errors.LA0175_Error.LogAttribute.OnEntry(PostSharp.Aspects.MethodExecutionArgs)" to method "Errors.LA0175_Error.PriceService.GetPriceAsync(System.String)": OnMethodBoundary semantic advising currently can be applied only to iterator and enumerable methods, async methods and any methods returning Task, Task<T>, IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T> without by-reference parameters. You can suppress this error message by setting the UnsupportedTargetAction property on the master advice.
Resolution
- Make the method return a Task or a Task<TResult>, or remove its
refandoutparameters. - Set the UnsupportedTargetAction property of the master advice to Fallback, so that the advices wrap the method itself, or to Ignore to skip the method.
- Exclude the method from semantic advising with the SemanticallyAdvisedMethodKinds property of the master advice.
In the following example, the method returns a Task<decimal>, for which PostSharp generates the state machine.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0175_Fixed;
[PSerializable]
public class LogAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
[OnMethodExitAdvice]
public void OnExit( MethodExecutionArgs args ) => Console.WriteLine( $"Leaving {args.Method.Name}." );
}
public class PriceService
{
// The method returns a Task<T>, so PostSharp runs OnExit when the task completes.
[Log]
public Task<decimal> GetPriceAsync( string product )
{
return Task.FromResult( product.Length * 1.5m );
}
}
public static class Program
{
public static async Task Main()
{
Console.WriteLine( await new PriceService().GetPriceAsync( "Coffee" ) );
}
}
Entering GetPriceAsync.
Leaving GetPriceAsync.
9.0
See Also
Reference
OnMethodBoundaryAdvice
UnsupportedTargetAction
Other Resources
Advice Methods
Semantic Advising of Iterator and Async Methods