| Severity | Error |
| Reported by | PostSharp |
| Message | The parameter "<Parameter>" of the advice "<Advice>" is bound by [ImportMember] without a member name, but a parameter of type "<ParameterType>" imports a member by name only. Specify the name of the member. |
Cause
Without a member name, ImportMemberAttribute selects a field or a property of the target type by its type. Some types of parameters give no type to select a member by, or import members that are always selected by name, as ImportMemberAttribute does on an aspect field:
- ILocationBinding, which reads and writes a field or a property of any type;
- IMethodBinding, which calls a method;
- Property<TValue> and Event<TDelegate>, which import a property or an event.
PostSharp reports LA0284 on the advice parameter when the attribute has none of these names, before it looks at any target.
In the following example, the [TraceStatus] aspect imports a member of Order as an ILocationBinding, but does not say which one.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0284_Error;
[PSerializable]
public sealed class TraceStatusAttribute : MethodLevelAspect
{
[OnMethodSuccessAdvice]
public static void OnSuccess( [This] object instance,
// ILocationBinding has no type by which PostSharp could select a member.
[ImportMember] ILocationBinding status )
{
object target = instance;
Console.WriteLine( "{0} = {1}", status.LocationInfo.Name, status.GetValue( ref target, Arguments.Empty ) );
}
}
public enum OrderStatus
{
New,
Shipped
}
public class Order
{
private OrderStatus status;
public OrderStatus Status => this.status;
[TraceStatus]
public void Ship() => this.status = OrderStatus.Shipped;
}
public static class Program
{
public static void Main()
{
new Order().Ship();
}
}
error LA0284: LA0284_Error.cs(14,67): The parameter "status" of the advice "Errors.LA0284_Error.TraceStatusAttribute.OnSuccess(System.Object, PostSharp.Aspects.ILocationBinding)" is bound by [ImportMember] without a member name, but a parameter of type "PostSharp.Aspects.ILocationBinding" imports a member by name only. Specify the name of the member.
Resolution
- Specify the name of the member in the constructor of ImportMemberAttribute. When the targets name the member differently, give several names, in order of precedence.
- For a field or a property, you can instead use ILocationBinding<T>, which selects the member by the type argument when there is no name.
In the following example, the aspect imports the status field by its name.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0284_Fixed;
[PSerializable]
public sealed class TraceStatusAttribute : MethodLevelAspect
{
[OnMethodSuccessAdvice]
public static void OnSuccess( [This] object instance,
// The name selects the member that the binding reads.
[ImportMember( "status" )] ILocationBinding status )
{
object target = instance;
Console.WriteLine( "{0} = {1}", status.LocationInfo.Name, status.GetValue( ref target, Arguments.Empty ) );
}
}
public enum OrderStatus
{
New,
Shipped
}
public class Order
{
private OrderStatus status;
public OrderStatus Status => this.status;
[TraceStatus]
public void Ship() => this.status = OrderStatus.Shipped;
}
public static class Program
{
public static void Main()
{
new Order().Ship();
}
}
status = Shipped
See Also
Reference
ImportMemberAttribute
ILocationBinding
ILocationBinding<T>
Other Resources