| Severity | Error |
| Reported by | PostSharp |
| Message | The parameter "<Parameter>" of the advice "<Advice>" is bound by [Argument("<Name>")], but "<TargetMethod>" has no parameter named "<Name>". |
Cause
The ArgumentAttribute(string) constructor binds a parameter of an advice to the argument of the target method that has a given name. PostSharp looks for the name in each target method of the advice, with a case-sensitive comparison. When a target method has no parameter of this name, it reports LA0226 on that method.
When the advice uses a pointcut that skips the targets whose signature does not match, such as MatchPointcut, PostSharp skips the target instead of reporting the error.
In the following example, the [LogCustomer] aspect reads the customerId argument, but the CountInvoices method names its parameter id.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0226_Error;
[PSerializable]
public sealed class LogCustomerAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( [DeclarationName] string methodName, [Argument( "customerId" )] int customerId )
{
Console.WriteLine( $"{methodName}: customer {customerId}" );
}
}
public class OrderService
{
[LogCustomer]
public int CountOrders( int customerId ) => 3;
// The parameter is named id, not customerId.
[LogCustomer]
public int CountInvoices( int id ) => 2;
}
public static class Program
{
public static void Main()
{
OrderService service = new();
Console.WriteLine( service.CountOrders( 42 ) );
Console.WriteLine( service.CountInvoices( 42 ) );
}
}
error LA0226: LA0226_Error.cs(25,16): The parameter "customerId" of the advice "Errors.LA0226_Error.LogCustomerAttribute.OnEntry(System.String, System.Int32)" is bound by [Argument("customerId")], but "Errors.LA0226_Error.OrderService.CountInvoices(System.Int32)" has no parameter named "customerId".
Resolution
- Rename the parameter of the target method, or the name given to the ArgumentAttribute, so that they match, including the case.
- Select the argument by its index or by its type when the target methods do not name it in the same way.
- Otherwise, apply the aspect only to methods that have a parameter of this name.
In the following example, the parameter of CountInvoices has the name that the aspect expects.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0226_Fixed;
[PSerializable]
public sealed class LogCustomerAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( [DeclarationName] string methodName, [Argument( "customerId" )] int customerId )
{
Console.WriteLine( $"{methodName}: customer {customerId}" );
}
}
public class OrderService
{
[LogCustomer]
public int CountOrders( int customerId ) => 3;
// The parameter has the name that the aspect expects.
[LogCustomer]
public int CountInvoices( int customerId ) => 2;
}
public static class Program
{
public static void Main()
{
OrderService service = new();
Console.WriteLine( service.CountOrders( 42 ) );
Console.WriteLine( service.CountInvoices( 42 ) );
}
}
CountOrders: customer 42
3
CountInvoices: customer 42
2
See Also
Reference
ArgumentAttribute
MatchPointcut
Other Resources