Open sandboxFocusImprove this doc

LA0273: Several Fields Match an Unnamed Field Request

Severity Error
Reported by PostSharp
Message The aspect "<Aspect>" applied to "<Target>" attempts to introduce a field of type "<FieldType>" in "<TargetType>" without a name, and several existing fields of this type could be used instead: <Fields>. Give the IntroduceFieldAdviceInstance a name, or set its WhenCompatibleFieldExists property to IntroduceAnother to introduce a new field.

Cause

An aspect attempts to introduce a field in its target type by returning an IntroduceFieldAdviceInstance. When the request has no Name, PostSharp recognizes an existing field by its type and its static or instance kind only, among the fields of the target type and the accessible fields of its base types. When several fields match, PostSharp cannot choose one and reports LA0273.

This happens whatever the WhenCompatibleFieldExists property of the request, except IntroduceAnother, which introduces a new field without choosing among the existing ones. When exactly one field matches and WhenCompatibleFieldExists is Fail, PostSharp reports LA0271 instead. LA0273 is always an error.

<Target> is the declaration to which the aspect is applied, where the error is located, and <Fields> lists the matching fields.

In the following example, the [CountCalls] aspect attempts to introduce an int field without a name, and OrderService declares two int fields, callCount and failureCount.

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

namespace Errors.LA0273_Error;

[PSerializable]
public sealed class CountCallsAttribute : MethodLevelAspect, IAdviceProvider
{
    public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
    {
        yield return new IntroduceFieldAdviceInstance( typeof(int) ) { WhenCompatibleFieldExists = IntroduceFieldCompatibleAction.Ignore };
    }

    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "callCount" )] ref int callCount )
    {
        callCount++;
    }
}

public class OrderService
{
    private int callCount;
    private int failureCount;

    public int CallCount => this.callCount;

    public int FailureCount => this.failureCount;

    public void ResetCounts()
    {
        this.callCount = 0;
        this.failureCount = 0;
    }

    // The aspect requests an int field without a name, and OrderService declares two.
    [CountCalls]
    public void PlaceOrder( string product )
    {
        if ( product.Length == 0 )
        {
            this.failureCount++;
            return;
        }

        Console.WriteLine( $"Placing an order for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        var service = new OrderService();
        service.PlaceOrder( "a book" );
        service.PlaceOrder( "" );
        Console.WriteLine( $"{service.CallCount} calls, {service.FailureCount} failure." );
    }
}
error LA0273: LA0273_Error.cs(41,17): The aspect "Errors.LA0273_Error.CountCallsAttribute" applied to "Errors.LA0273_Error.OrderService.PlaceOrder(System.String)" attempts to introduce a field of type "int32" in "Errors.LA0273_Error.OrderService" without a name, and several existing fields of this type could be used instead: "callCount", "failureCount". Give the IntroduceFieldAdviceInstance a name, or set its WhenCompatibleFieldExists property to IntroduceAnother to introduce a new field.

Resolution

In the following example, the request names the callCount field, and the aspect counts the calls in this field.

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

namespace Errors.LA0273_Fixed;

[PSerializable]
public sealed class CountCallsAttribute : MethodLevelAspect, IAdviceProvider
{
    public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
    {
        // The name selects the callCount field.
        yield return new IntroduceFieldAdviceInstance( typeof(int) ) { Name = "callCount", WhenCompatibleFieldExists = IntroduceFieldCompatibleAction.Ignore };
    }

    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "callCount" )] ref int callCount )
    {
        callCount++;
    }
}

public class OrderService
{
    private int callCount;
    private int failureCount;

    public int CallCount => this.callCount;

    public int FailureCount => this.failureCount;

    public void ResetCounts()
    {
        this.callCount = 0;
        this.failureCount = 0;
    }

    [CountCalls]
    public void PlaceOrder( string product )
    {
        if ( product.Length == 0 )
        {
            this.failureCount++;
            return;
        }

        Console.WriteLine( $"Placing an order for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        var service = new OrderService();
        service.PlaceOrder( "a book" );
        service.PlaceOrder( "" );
        Console.WriteLine( $"{service.CallCount} calls, {service.FailureCount} failure." );
    }
}
Placing an order for a book.
2 calls, 1 failure.

See Also

Reference

IntroduceFieldAdviceInstance
IntroduceFieldCompatibleAction
ImportMemberAttribute

Other Resources

Providing Advices Dynamically