| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply the aspect "<Aspect>" to method "<Method>": 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 aspect. |
Cause
By default, OnMethodBoundaryAspect and OnExceptionAspect advise semantically the methods that return an awaitable type, also when they are not async: OnExit runs when the task completes, not when the method returns it. 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 LA0174 on the target method when it should advise the method semantically, cannot generate the state machine, and the UnsupportedTargetAction property of the aspect keeps its default value, Fail. The typical case is a method that returns a ValueTask<TResult> without the async keyword.
In the following example, the [Log] aspect is applied to a method that returns a ValueTask<decimal> and is not async.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0174_Error;
[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
public override 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 LA0174: LA0174_Error.cs(20,31): Cannot apply the aspect "Errors.LA0174_Error.LogAttribute" to method "Errors.LA0174_Error.PriceService.GetPriceAsync(System.String)": 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 aspect.
Resolution
- Set the UnsupportedTargetAction property of the aspect to Fallback, so that the aspect wraps the method itself, or to Ignore to skip the method.
- Make the method return a Task or a Task<TResult>, or remove its
refandoutparameters. - Exclude the method from semantic advising with the SemanticallyAdvisedMethodKinds property.
In the following example, the aspect falls back to non-semantic advising. OnExit runs when the method returns its ValueTask<decimal>.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0174_Fixed;
[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry( MethodExecutionArgs args ) => Console.WriteLine( $"Entering {args.Method.Name}." );
public override void OnExit( MethodExecutionArgs args ) => Console.WriteLine( $"Leaving {args.Method.Name}." );
}
public class PriceService
{
// The aspect falls back to non-semantic advising: it wraps the method, not the task that the method returns.
[Log( UnsupportedTargetAction = UnsupportedTargetAction.Fallback )]
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" ) );
}
}
Entering GetPriceAsync.
Leaving GetPriceAsync.
9.0
See Also
Reference
OnMethodBoundaryAspect
OnExceptionAspect
UnsupportedTargetAction
Other Resources