| Severity | Error |
| Reported by | PostSharp |
| Message | The parameter "<Parameter>" of the advice "<Advice>" is bound by [Argument] to an argument of its type, but several parameters of "<TargetMethod>" match: <MatchingParameters>. Select the argument by its index or by its name, or set the AmbiguityResolution property. |
Cause
The ArgumentAttribute constructor without parameter selects the argument of the target method by its type: the argument whose type can be assigned to the type of the advice parameter without conversion, except boxing. When several parameters of the target method match, the AmbiguityResolution property decides which one is bound. Its default value, Error, reports LA0228 rather than choosing an argument that the aspect may not expect.
<MatchingParameters> lists the names of the matching parameters of <TargetMethod>. PostSharp reports the message on the target method, not on the advice, and once for each target method where the ambiguity occurs. A parameter of type object matches every parameter of the target method.
In the following example, the OnEntry advice expects the amount of a payment, but the Charge method has two parameters of type decimal.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0228_Error;
[PSerializable]
public class LogAmountAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( [Argument] decimal amount )
{
Console.WriteLine( $"Amount: {amount}" );
}
}
public class PaymentService
{
// Both parameters are of type decimal, so [Argument] cannot select one by its type.
[LogAmount]
public void Charge( decimal amount, decimal fee )
{
Console.WriteLine( $"Charged {amount + fee}." );
}
}
public static class Program
{
public static void Main()
{
new PaymentService().Charge( 100m, 2.5m );
}
}
error LA0228: LA0228_Error.cs(22,17): The parameter "amount" of the advice "Errors.LA0228_Error.LogAmountAttribute.OnEntry(System.Decimal)" is bound by [Argument] to an argument of its type, but several parameters of "Errors.LA0228_Error.PaymentService.Charge(System.Decimal, System.Decimal)" match: amount, fee. Select the argument by its index or by its name, or set the AmbiguityResolution property.
Resolution
- Select the argument by its name with the ArgumentAttribute(string) constructor, or by its index with the ArgumentAttribute(int) constructor.
- Set AmbiguityResolution to First or Last to bind the first or the last matching argument, in the order of the parameter list.
- Make the type of the advice parameter more specific, so that only one parameter of the target method matches it.
In the following example, the advice selects the amount argument by its name.
using System;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0228_Fixed;
[PSerializable]
public class LogAmountAttribute : MethodLevelAspect
{
// The argument is selected by its name.
[OnMethodEntryAdvice]
public void OnEntry( [Argument( "amount" )] decimal amount )
{
Console.WriteLine( $"Amount: {amount}" );
}
}
public class PaymentService
{
[LogAmount]
public void Charge( decimal amount, decimal fee )
{
Console.WriteLine( $"Charged {amount + fee}." );
}
}
public static class Program
{
public static void Main()
{
new PaymentService().Charge( 100m, 2.5m );
}
}
Amount: 100
Charged 102.5.
See Also
Reference
ArgumentAttribute
ArgumentAmbiguityResolution
Other Resources