| Severity | Error |
| Reported by | PostSharp |
| Message | The aspect "<Aspect>" applied to "<Target>" attempts to introduce a field of type "<FieldType>" with IntroduceFieldAdviceInstance, which is not a valid field type. By-reference types, pointers, void and types that contain generic parameters are not supported, and a byref-like type, such as Span<T>, is supported only as an instance field of a ref struct. |
Cause
An aspect attempts to introduce a field by returning an IntroduceFieldAdviceInstance from ProvideAdvices. PostSharp reports LA0269 when the FieldType of the request is one of the following:
- A by-reference type, such as the type of a
refparameter. - A pointer type, such as
byte*. void.- A type that contains generic parameters, such as the return type
Tof a generic method, or an open generic type. - A byref-like type, such as Span<T>, when the request is for a static field (IsStatic is
true) or when the target type is not aref struct.
<Target> is the declaration to which the aspect is applied, where the error is located.
In the following example, the [NativeBuffer] aspect attempts to introduce a field of type byte* to store the address of a native buffer.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0269_Error;
// Gives each object a native buffer, allocated on the first call of the target method.
[PSerializable]
public sealed unsafe class NativeBufferAttribute : MethodLevelAspect, IAdviceProvider
{
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
// A pointer is not a valid type for a requested field.
yield return new IntroduceFieldAdviceInstance( typeof(byte*) ) { Name = "buffer" };
}
[OnMethodEntryAdvice]
public static void OnEntry( [ImportMember( "buffer" )] ref byte* buffer )
{
if ( buffer == null )
{
buffer = (byte*) Marshal.AllocHGlobal( 256 );
Console.WriteLine( "Allocated a native buffer." );
}
}
}
public class Encoder
{
[NativeBuffer]
public void Encode( string text ) => Console.WriteLine( $"Encoding \"{text}\"." );
}
public static class Program
{
public static void Main()
{
Encoder encoder = new Encoder();
encoder.Encode( "first" );
encoder.Encode( "second" );
}
}
error LA0269: LA0269_Error.cs(34,17): The aspect "Errors.LA0269_Error.NativeBufferAttribute" applied to "Errors.LA0269_Error.Encoder.Encode(System.String)" attempts to introduce a field of type "System.Byte*" with IntroduceFieldAdviceInstance, which is not a valid field type. By-reference types, pointers, void and types that contain generic parameters are not supported, and a byref-like type, such as Span<T>, is supported only as an instance field of a ref struct.
Resolution
Request a field of a type that a field can have:
- For a pointer, request a nint (
nint) field, and convert it to a pointer in the advice. - For a by-reference type, request a field of the element type, which GetElementType returns.
- For a type that depends on a generic parameter of a method, request a field of a closed type, such as object.
- For a byref-like type, request an instance field in a
ref struct, or store the data in a type that is not byref-like, such as an array or Memory<T>.
In the following example, the aspect stores the address of the buffer in an nint field, and allocates the buffer once for each object.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0269_Fixed;
// Gives each object a native buffer, allocated on the first call of the target method.
[PSerializable]
public sealed class NativeBufferAttribute : MethodLevelAspect, IAdviceProvider
{
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
// The address of the buffer is stored in a native-sized integer.
yield return new IntroduceFieldAdviceInstance( typeof(nint) ) { Name = "buffer" };
}
[OnMethodEntryAdvice]
public static void OnEntry( [ImportMember( "buffer" )] ref nint buffer )
{
if ( buffer == 0 )
{
buffer = Marshal.AllocHGlobal( 256 );
Console.WriteLine( "Allocated a native buffer." );
}
}
}
public class Encoder
{
[NativeBuffer]
public void Encode( string text ) => Console.WriteLine( $"Encoding \"{text}\"." );
}
public static class Program
{
public static void Main()
{
Encoder encoder = new Encoder();
encoder.Encode( "first" );
encoder.Encode( "second" );
}
}
Allocated a native buffer.
Encoding "first".
Encoding "second".
See Also
Reference
IntroduceFieldAdviceInstance
ImportMemberAttribute
Other Resources