Open sandboxFocusImprove this doc

LA0282: Instance Field Imported by Reference on a Static Target

Severity Error
Reported by PostSharp
Message The parameter "<Parameter>" of the advice "<Advice>" is bound by [ImportMember] and passed by reference to the instance field "<Field>", but "<Target>" is static and has no instance. Pass the parameter by value, which receives the default value on a static target.

Cause

An advice parameter annotated with ImportMemberAttribute and passed as in, ref or out receives a reference to a field of the target object. When the advice is applied to a static member, there is no target object, so an instance field has no storage that the parameter could reference, and PostSharp reports LA0282 on the static member.

A parameter passed by value does not cause this error: on a static target, it receives the default value of an instance member.

In the following example, the [CountCalls] aspect increments the callCount instance field, and it is also applied to the static Create method.

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

namespace Errors.LA0282_Error;

[PSerializable]
public class CountCallsAttribute : MethodLevelAspect
{
    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "callCount" )] ref int callCount )
    {
        callCount++;
    }
}

public class OrderService
{
    private int callCount = 0;

    public int CallCount => this.callCount;

    // A static method has no instance, so it has no callCount field.
    [CountCalls]
    public static OrderService Create() => new OrderService();

    [CountCalls]
    public void PlaceOrder( string product ) => Console.WriteLine( $"Ordered {product}" );
}

public static class Program
{
    public static void Main()
    {
        OrderService service = OrderService.Create();
        service.PlaceOrder( "Coffee" );
        service.PlaceOrder( "Tea" );
        Console.WriteLine( $"Calls: {service.CallCount}" );
    }
}
error LA0282: LA0282_Error.cs(26,32): The parameter "callCount" of the advice "Errors.LA0282_Error.CountCallsAttribute.OnEntry(System.Int32@)" is bound by [ImportMember] and passed by reference to the instance field "Errors.LA0282_Error.OrderService.callCount", but "Errors.LA0282_Error.OrderService.Create" is static and has no instance. Pass the parameter by value, which receives the default value on a static target.

Resolution

Choose one of the following:

  • Make the field static, when its value does not belong to one object. A static field can be imported by reference on any target.
  • Do not apply the aspect to static members. When you apply it with multicasting, exclude them with AttributeTargetMemberAttributes = MulticastAttributes.Instance.
  • Pass the parameter by value, when the advice only reads the field and can accept the default value on a static target.

In the following example, the call counter is a static field, so it also counts the calls of the static Create method.

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

namespace Errors.LA0282_Fixed;

[PSerializable]
public class CountCallsAttribute : MethodLevelAspect
{
    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "callCount" )] ref int callCount )
    {
        callCount++;
    }
}

public class OrderService
{
    // A static field exists without an instance, so the static method can increment it too.
    private static int callCount = 0;

    public int CallCount => callCount;

    [CountCalls]
    public static OrderService Create() => new OrderService();

    [CountCalls]
    public void PlaceOrder( string product ) => Console.WriteLine( $"Ordered {product}" );
}

public static class Program
{
    public static void Main()
    {
        OrderService service = OrderService.Create();
        service.PlaceOrder( "Coffee" );
        service.PlaceOrder( "Tea" );
        Console.WriteLine( $"Calls: {service.CallCount}" );
    }
}
Ordered Coffee
Ordered Tea
Calls: 3

See Also

Reference

ImportMemberAttribute

Other Resources

Advice Parameters