Open sandboxFocusImprove this doc

LA0235: Argument Passed by Reference in an Interception Advice

Severity Warning
Reported by PostSharp
Message The parameter "<Parameter>" of the advice "<Advice>" is bound by <Binding> and passed as out or ref, but a value that an interception advice writes to it does not reach the intercepted method. Change the argument through the Arguments object passed to the binding, or pass the parameter by value or as in.

Cause

In a method boundary advice, an ArgumentAttribute parameter passed as out or ref changes the argument that the method body sees. In an OnMethodInvokeAdvice, it does not: the advice calls the intercepted method through Invoke, which passes the arguments of the Arguments object, not the parameter of the advice. PostSharp reports LA0235 on each out or ref [Argument] parameter of an interception advice.

<Binding> is the attribute as written, such as [Argument(0)].

In the following example, the [TrimFirstArgument] aspect trims the name through a ref parameter, but Greet receives the name with its spaces.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;

namespace Errors.LA0235_Error;

[PSerializable]
public class TrimFirstArgumentAttribute : MethodLevelAspect
{
    [OnMethodInvokeAdvice]
    public static void OnInvoke<T>( [This] object instance,
                                    [Binding] IMethodBinding binding,
                                    [Arguments] Arguments arguments,
                                    // The value written to this ref parameter does not reach the intercepted method.
                                    [Argument( 0 )] ref string name,
                                    [ReturnValue] out T returnValue )
    {
        name = name.Trim();
        returnValue = (T) binding.Invoke( ref instance, arguments )!;
    }
}

public class Greeter
{
    [TrimFirstArgument]
    public string Greet( string name ) => $"Hello, [{name}]!";
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( new Greeter().Greet( "  Jane  " ) );
    }
}
warning LA0235: LA0235_Error.cs(16,64): The parameter "name" of the advice "Errors.LA0235_Error.TrimFirstArgumentAttribute.OnInvoke``1(System.Object, PostSharp.Aspects.IMethodBinding, PostSharp.Aspects.Arguments, System.String@, ``0@)" is bound by [Argument(0)] and passed as out or ref, but a value that an interception advice writes to it does not reach the intercepted method. Change the argument through the Arguments object passed to the binding, or pass the parameter by value or as in.
Hello, [  Jane  ]!

Resolution

Pass the [Argument] parameter by value or as in, and set the new value in the Arguments object that the advice passes to the binding, which an ArgumentsAttribute parameter provides.

In the following example, the advice reads the name by value and sets the trimmed name in arguments.

using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;

namespace Errors.LA0235_Fixed;

[PSerializable]
public class TrimFirstArgumentAttribute : MethodLevelAspect
{
    [OnMethodInvokeAdvice]
    public static void OnInvoke<T>( [This] object instance,
                                    [Binding] IMethodBinding binding,
                                    [Arguments] Arguments arguments,
                                    [Argument( 0 )] string name,
                                    [ReturnValue] out T returnValue )
    {
        // The new value is set in the Arguments object passed to the binding.
        arguments[0] = name.Trim();
        returnValue = (T) binding.Invoke( ref instance, arguments )!;
    }
}

public class Greeter
{
    [TrimFirstArgument]
    public string Greet( string name ) => $"Hello, [{name}]!";
}

public static class Program
{
    public static void Main()
    {
        Console.WriteLine( new Greeter().Greet( "  Jane  " ) );
    }
}
Hello, [Jane]!

See Also

Reference

ArgumentAttribute
OnMethodInvokeAdvice
Arguments
IMethodBinding

Other Resources

Advice Parameters