| Severity | Error |
| Reported by | PostSharp |
| Message | The parameter "<Parameter>" of the advice "<Advice>" is bound by [ReturnValue] with IsRequired set to true, but "<TargetMethod>" has no return value that the advice can access: it returns void, returns a task without a result, returns by reference, or is an iterator. |
Cause
A parameter annotated with ReturnValueAttribute reads or sets the return value of the target method. When the target method has no return value that the advice can access, the parameter receives the default value of its type, and a value that the advice writes to it is ignored. When IsRequired is true, PostSharp reports LA0241 on such a target method instead:
- In a method boundary advice, a method that returns
void, a Task or a ValueTask without a result, or a reference (reforref readonly), and an iterator. - In an OnMethodInvokeAdvice, a method that returns
void.
In the following example, the [LogResult] aspect is applied to a method that returns void.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0241_Error;
[PSerializable]
public class LogResultAttribute : MethodLevelAspect
{
[OnMethodSuccessAdvice]
public static void OnSuccess( [DeclarationName] string methodName, [ReturnValue( IsRequired = true )] object? value )
{
Console.WriteLine( $"{methodName} returned {value}." );
}
}
public class OrderService
{
private int count = 3;
[LogResult]
public int CountOrders() => this.count;
// The method returns void, so it has no value that the aspect can log.
[LogResult]
public void ClearOrders() => this.count = 0;
}
public static class Program
{
public static void Main()
{
OrderService service = new OrderService();
service.CountOrders();
service.ClearOrders();
service.CountOrders();
}
}
error LA0241: LA0241_Error.cs(27,17): The parameter "value" of the advice "Errors.LA0241_Error.LogResultAttribute.OnSuccess(System.String, System.Object)" is bound by [ReturnValue] with IsRequired set to true, but "Errors.LA0241_Error.OrderService.ClearOrders" has no return value that the advice can access: it returns void, returns a task without a result, returns by reference, or is an iterator.
Resolution
- Apply the aspect only to methods that return a value. In a type-level aspect, a MatchPointcut skips the methods without a return value instead of reporting the error.
- Or, when the advice can do without the return value, set IsRequired to
false.
In the following example, the aspect is removed from the method that returns void.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0241_Fixed;
[PSerializable]
public class LogResultAttribute : MethodLevelAspect
{
[OnMethodSuccessAdvice]
public static void OnSuccess( [DeclarationName] string methodName, [ReturnValue( IsRequired = true )] object? value )
{
Console.WriteLine( $"{methodName} returned {value}." );
}
}
public class OrderService
{
private int count = 3;
[LogResult]
public int CountOrders() => this.count;
// The aspect is applied only to methods that return a value.
public void ClearOrders() => this.count = 0;
}
public static class Program
{
public static void Main()
{
OrderService service = new OrderService();
service.CountOrders();
service.ClearOrders();
service.CountOrders();
}
}
CountOrders returned 3.
CountOrders returned 0.
See Also
Reference
ReturnValueAttribute
OnMethodSuccessAdvice
Other Resources