| Severity | Error |
| Reported by | PostSharp |
| Message | The aspect "<Aspect>" cannot be applied to "<Target>": <Reason> |
Cause
An aspect checks at build time that it can be applied to its target, in its CompileTimeValidate method, such as CompileTimeValidate(MethodBase) for a method-level aspect. To reject the target with an error, the method can throw an InvalidAnnotationException. PostSharp then reports LA0252 on the target, without a stack trace, and does not apply the aspect to it.
<Reason> is the message of the exception, which the author of the aspect writes. Any other exception thrown by CompileTimeValidate is reported as an unexpected exception of the aspect, with its stack trace.
In the following example, the [CacheResult] aspect rejects methods that return void, and is applied to ClearPrices, which does.
using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.LA0252_Error;
[PSerializable]
public class CacheResultAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate( MethodBase method )
{
if ( ((MethodInfo) method).ReturnType == typeof(void) )
{
throw new InvalidAnnotationException( "The method returns void, so it has no result to cache." );
}
return true;
}
public override void OnSuccess( MethodExecutionArgs args )
=> Console.WriteLine( $"Caching the result of {args.Method.Name}: {args.ReturnValue}." );
}
public class PriceService
{
[CacheResult]
public decimal GetPrice( string sku ) => 9.99m;
// The method returns void, so CompileTimeValidate rejects the aspect.
[CacheResult]
public void ClearPrices() => Console.WriteLine( "Prices cleared." );
}
public static class Program
{
public static void Main()
{
PriceService service = new();
Console.WriteLine( service.GetPrice( "BOOK-1" ) );
service.ClearPrices();
}
}
error LA0252: LA0252_Error.cs(33,17): The aspect "Errors.LA0252_Error.CacheResultAttribute" cannot be applied to "Errors.LA0252_Error.PriceService.ClearPrices": The method returns void, so it has no result to cache.
Resolution
Read the reason in the message, which tells what the aspect requires:
- Remove the aspect from the target, or change the target so that it fits the requirements of the aspect.
- When the aspect is applied by multicasting, exclude the target, for instance with AttributeExclude or by narrowing the multicast filters.
- If you are the author of the aspect and the aspect should skip such targets silently, return
falsefromCompileTimeValidateinstead of throwing the exception.
In the following example, the aspect is no longer applied to ClearPrices.
using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.LA0252_Fixed;
[PSerializable]
public class CacheResultAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate( MethodBase method )
{
if ( ((MethodInfo) method).ReturnType == typeof(void) )
{
throw new InvalidAnnotationException( "The method returns void, so it has no result to cache." );
}
return true;
}
public override void OnSuccess( MethodExecutionArgs args )
=> Console.WriteLine( $"Caching the result of {args.Method.Name}: {args.ReturnValue}." );
}
public class PriceService
{
[CacheResult]
public decimal GetPrice( string sku ) => 9.99m;
// The aspect is no longer applied to a method that returns void.
public void ClearPrices() => Console.WriteLine( "Prices cleared." );
}
public static class Program
{
public static void Main()
{
PriceService service = new();
Console.WriteLine( service.GetPrice( "BOOK-1" ) );
service.ClearPrices();
}
}
Caching the result of GetPrice: 9.99.
9.99
Prices cleared.
See Also
Reference
InvalidAnnotationException
CompileTimeValidate(object)
Other Resources