Open sandboxFocusImprove this doc

LA0241: Required Return Value Not Available

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 (ref or ref 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

Advice Parameters