Open sandboxFocusImprove this doc

LA0268: Field Requested in a Type That Cannot Have Fields

Severity Error
Reported by PostSharp
Message The aspect "<Aspect>" applied to "<Target>" attempts to introduce a field with IntroduceFieldAdviceInstance, but a field cannot be introduced into "<TargetType>". Fields can be introduced into classes and structs only.

Cause

An aspect attempts to introduce a field by returning an IntroduceFieldAdviceInstance from ProvideAdvices. The field goes into the target type: the type to which the aspect is applied, or the type that declares the member to which it is applied. Only a class or a struct can receive the field. PostSharp reports LA0268 when the target type is an interface, an enum or a delegate, and when the aspect is applied to an assembly, which has no target type; <TargetType> is then the assembly.

<Target> is the declaration to which the aspect is applied, where the error is located.

In the following example, the [RunOnce] aspect, which stores a flag in each object, is applied to a method of the IConnection interface.

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

namespace Errors.LA0268_Error;

[PSerializable]
public sealed class RunOnceAttribute : MethodLevelAspect, IAdviceProvider
{
    public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
    {
        // A flag in the type that declares the target method.
        yield return new IntroduceFieldAdviceInstance( typeof(bool) ) { Name = "hasRun" };
    }

    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "hasRun" )] ref bool hasRun, [FlowBehavior] out FlowBehavior flowBehavior )
    {
        flowBehavior = hasRun ? FlowBehavior.Return : FlowBehavior.Default;
        hasRun = true;
    }
}

public interface IConnection
{
    // The method is declared by an interface, which cannot have instance fields.
    [RunOnce]
    void Open();
}

public class Connection : IConnection
{
    public void Open() => Console.WriteLine( "Opening the connection." );
}

public static class Program
{
    public static void Main()
    {
        IConnection connection = new Connection();
        connection.Open();
        connection.Open();
    }
}
error LA0268: LA0268_Error.cs(30,10): The aspect "Errors.LA0268_Error.RunOnceAttribute" applied to "Errors.LA0268_Error.IConnection.Open" attempts to introduce a field with IntroduceFieldAdviceInstance, but a field cannot be introduced into "Errors.LA0268_Error.IConnection". Fields can be introduced into classes and structs only.

Resolution

Apply the aspect to a class or a struct, or to a member of a class or a struct. When the aspect is meant for the implementations of an interface, apply it to the methods of the classes that implement the interface.

In the following example, the aspect is applied to the Open method of the Connection class, and the second call does nothing.

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

namespace Errors.LA0268_Fixed;

[PSerializable]
public sealed class RunOnceAttribute : MethodLevelAspect, IAdviceProvider
{
    public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
    {
        // A flag in the type that declares the target method.
        yield return new IntroduceFieldAdviceInstance( typeof(bool) ) { Name = "hasRun" };
    }

    [OnMethodEntryAdvice]
    public static void OnEntry( [ImportMember( "hasRun" )] ref bool hasRun, [FlowBehavior] out FlowBehavior flowBehavior )
    {
        flowBehavior = hasRun ? FlowBehavior.Return : FlowBehavior.Default;
        hasRun = true;
    }
}

public interface IConnection
{
    void Open();
}

public class Connection : IConnection
{
    // The aspect is applied to the implementation, in a class that receives the field.
    [RunOnce]
    public void Open() => Console.WriteLine( "Opening the connection." );
}

public static class Program
{
    public static void Main()
    {
        IConnection connection = new Connection();
        connection.Open();
        connection.Open();
    }
}
Opening the connection.

See Also

Reference

IntroduceFieldAdviceInstance
IAdviceProvider

Other Resources

Providing Advices Dynamically