| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The scope of the anonymous method or lambda expression with a block body cannot be determined. Use 'meta.RunTime' or 'meta.CompileTime' to resolve the ambiguity. |
Cause
In a template, every statement is either compile-time, meaning that it runs during compilation, or run-time, meaning that it's copied to the generated code. For a lambda expression with an expression body, Metalama infers the scope from the expression. For a lambda expression with a block body, or for an anonymous method (delegate { ... }), Metalama must learn the scope from the context, for instance from the run-time method to which the lambda is passed as an argument.
Metalama reports LAMA0284 when such a lambda or anonymous method appears in a context that doesn't determine its scope, for instance when it's assigned to a local variable.
In the following example, a lambda with a block body is assigned to a local variable of type Action.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0284.Error;
5
6public class LogReturnValueAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Metalama can't determine whether this lambda block is compile-time or run-time.
Error LAMA0284: The scope of the anonymous method or lambda expression with a block body cannot be determined. Use 'meta.RunTime' or 'meta.CompileTime' to resolve the ambiguity.
11 Action<object?> log = value => { Console.WriteLine( value?.ToString() ); };
12
13 var result = meta.Proceed();
14 log( result );
15
16 return result;
17 }
18}
19
1namespace Doc.LAMA0284.Error;
2
3public class Calculator
4{
5 [LogReturnValue]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Make the scope of the lambda or anonymous method explicit:
- To include it in the generated code, wrap it in meta.RunTime, for instance
meta.RunTime( new Action<object?>( ... ) ), as in the following example. - To run it at compile time, wrap it in meta.CompileTime.
Alternatively, pass the lambda directly as an argument of a run-time method, which determines its scope.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0284.Fixed;
5
6public class LogReturnValueAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // meta.RunTime makes the lambda block run-time.
11 var log = meta.RunTime( new Action<object?>( value => { Console.WriteLine( value?.ToString() ); } ) );
12
13 var result = meta.Proceed();
14 log( result );
15
16 return result;
17 }
18}
19
1namespace Doc.LAMA0284.Fixed;
2
3public class Calculator
4{
5 [LogReturnValue]
6 public int Add( int a, int b ) => a + b;
7}
8
1using System;
2
3namespace Doc.LAMA0284.Fixed;
4
5public class Calculator
6{
7 [LogReturnValue]
8 public int Add(int a, int b)
9 {
10 var log = new Action<object?>(value => Console.WriteLine(value?.ToString()));
11 int result;
12 result = a + b;
13 log(result);
14 return result;
15 }
16}
17