| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The member '<Member>' requires at least <RequiredArgumentsCount> argument(s), but the invocation passes <ActualArgumentsCount>. |
Cause
In a template, you can generate a call to a method or a constructor that you only know as a compile-time declaration, such as an IMethod, by calling the Invoke method of its invoker. The C# compiler can't check the arguments of this call, because it doesn't know the signature of the target member when it compiles the aspect. Metalama checks them when it executes the template.
When the invoked member ends with a params parameter, you can pass any number of arguments for this parameter, including none, but you must pass one argument for each parameter that precedes it. Metalama reports LAMA0013 when you pass fewer arguments than that. In the message, <Member> is the invoked member, <RequiredArgumentsCount> is the number of parameters before the params parameter, and <ActualArgumentsCount> is the number of arguments passed to Invoke. The diagnostic is reported on the declaration to which the aspect is applied.
For a member without a params parameter, Metalama reports LAMA0012 instead.
In the following example, the Audit aspect calls the WriteAudit method of the target type without any argument, although the method requires a methodName argument before its params parameter.
1using Metalama.Framework.Aspects;
2using System.Linq;
3
4namespace Doc.LAMA0013.Error;
5
6public class AuditAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Finds the WriteAudit method of the target type.
11 var writeAudit = meta.Target.Type.Methods.OfName( "WriteAudit" ).Single();
12
13 // Error: WriteAudit requires at least the methodName argument, but no argument is passed.
14 writeAudit.Invoke();
15
16 return meta.Proceed();
17 }
18}
19
1using System;
2
3namespace Doc.LAMA0013.Error;
4
5internal class OrderService
6{
7 [Audit]
Error LAMA0013: The member 'OrderService.WriteAudit(string, params object?[])' requires at least 1 argument(s), but the invocation passes 0.
8 public void PlaceOrder( string product, int quantity )
9 {
10 Console.WriteLine( $"Placing an order for {quantity} {product}." );
11 }
12
13 private void WriteAudit( string methodName, params object?[] details )
14 {
15 Console.WriteLine( $"Audit: {methodName} ({details.Length} details)" );
16 }
17}
18
Resolution
Pass one argument for each parameter that precedes the params parameter, then any number of arguments for the params parameter. If your aspect must work with members of several signatures, examine the Parameters collection of the member before invoking it.
In the following example, the aspect passes the required methodName argument and no argument for the params parameter.
1using Metalama.Framework.Aspects;
2using System.Linq;
3
4namespace Doc.LAMA0013.Fixed;
5
6public class AuditAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Finds the WriteAudit method of the target type.
11 var writeAudit = meta.Target.Type.Methods.OfName( "WriteAudit" ).Single();
12
13 // Fixed: the required methodName argument is passed.
14 writeAudit.Invoke( meta.Target.Method.Name );
15
16 return meta.Proceed();
17 }
18}
19
1using System;
2
3namespace Doc.LAMA0013.Fixed;
4
5internal class OrderService
6{
7 [Audit]
8 public void PlaceOrder( string product, int quantity )
9 {
10 Console.WriteLine( $"Placing an order for {quantity} {product}." );
11 }
12
13 private void WriteAudit( string methodName, params object?[] details )
14 {
15 Console.WriteLine( $"Audit: {methodName} ({details.Length} details)" );
16 }
17}
18
1using System;
2
3namespace Doc.LAMA0013.Fixed;
4
5internal class OrderService
6{
7 [Audit]
8 public void PlaceOrder(string product, int quantity)
9 {
10 WriteAudit("PlaceOrder");
11 Console.WriteLine($"Placing an order for {quantity} {product}.");
12 }
13 private void WriteAudit(string methodName, params object?[] details)
14 {
15 Console.WriteLine($"Audit: {methodName} ({details.Length} details)");
16 }
17}
18