Open sandboxFocusImprove this doc

LAMA0275: A call to a virtual template can't omit optional arguments

Severity Error
Reported by Metalama.Framework
Message The template call '<Call>' omits arguments of optional parameters, which is not supported when the called template is virtual, abstract, or an override. Specify all arguments, or make the template non-virtual.

Cause

Auxiliary templates can be virtual, so that derived aspects can override them, and their parameters can have default values. However, Metalama currently doesn't support both at the same time: when a template calls an auxiliary template that is virtual, abstract, or a non-sealed override, the call must provide an argument for every parameter.

Metalama reports LAMA0275 when such a call has fewer arguments than the called template has parameters. The <Call> placeholder is the text of the call.

In the following example, the Log aspect calls the virtual LogEntry template without specifying its optional verb argument.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0275.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Error: the call to the virtual LogEntry template omits the optional argument.
        Error LAMA0275: The template call 'LogEntry()' omits arguments of optional parameters, which is not supported when the called template is virtual, abstract, or an override. Specify all arguments, or make the template non-virtual.

11        LogEntry();
12
13        return meta.Proceed();
14    }
15
16    // Derived aspects can override this template to customize the log message.
17    [Template]
18    protected virtual void LogEntry( [CompileTime] string verb = "Executing" )
19    {
20        Console.WriteLine( $"{verb} {meta.Target.Method}." );
21    }
22}
23
1namespace Doc.LAMA0275.Error;
2
3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8

Resolution

Do one of the following:

  • Specify all arguments in the call, including those of optional parameters.
  • If derived aspects don't need to override the template, remove the virtual modifier, or seal the overriding template, so that optional arguments can be omitted.

In the following example, the call specifies the value of the verb parameter.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0275.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Fixed: the call to the virtual LogEntry template specifies all arguments.
11        LogEntry( "Executing" );
12
13        return meta.Proceed();
14    }
15
16    // Derived aspects can override this template to customize the log message.
17    [Template]
18    protected virtual void LogEntry( [CompileTime] string verb = "Executing" )
19    {
20        Console.WriteLine( $"{verb} {meta.Target.Method}." );
21    }
22}
23
Source Code
1namespace Doc.LAMA0275.Fixed;
2


3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0275.Fixed;
4
5internal class Calculator
6{
7    [Log]
8    public int Add(int a, int b)
9    {
10        Console.WriteLine("Executing Calculator.Add(int, int).");
11        return a + b;
12    }
13}
14

See also