| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The 'dynamic' keyword cannot be used in the local variable '<Variable>' because it is not initialized. Initialize the variable in its declaration, or use 'meta.DefineLocalVariable' to declare a run-time variable without an initializer. |
Cause
In a T# template, dynamic stands for a run-time type that's only known when Metalama expands the template, for instance the return type of the target method. Metalama infers the actual type of a dynamic local variable from its initializer. Without an initializer, there's nothing to infer the type from.
Metalama reports LAMA0224 when a template declares a local variable of type dynamic (or dynamic?) without an initializer. The placeholder of the message is the name of the variable.
In the following example, the template declares result before a try block and assigns it inside the block.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0224.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Error: a variable of type dynamic must be initialized in its declaration.
Error LAMA0224: The 'dynamic' keyword cannot be used in the local variable 'result' because it is not initialized. Initialize the variable in its declaration, or use 'meta.DefineLocalVariable' to declare a run-time variable without an initializer.
11 dynamic? result;
12
13 try
14 {
15 result = meta.Proceed();
16 }
17 catch ( Exception e )
18 {
19 Console.WriteLine( $"{meta.Target.Method.Name} failed: {e.Message}" );
20
21 throw;
22 }
23
24 Console.WriteLine( $"{meta.Target.Method.Name} returned {result}." );
25
26 return result;
27 }
28}
29
1namespace Doc.LAMA0224.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Depending on your intent, do one of the following:
- Initialize the variable in its declaration. If needed, move the declaration to where the value is available, for instance inside the
tryblock, as shown in the following example. - Initialize the variable with a
dynamicexpression that gives it the right type, for instancemeta.Default( meta.Target.Method.ReturnType ). - Declare the variable with meta.DefineLocalVariable, passing its type, which generates a run-time variable without an initializer. Use the
Valueproperty of the returned expression to read or write the variable.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0224.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 try
11 {
12 // Fixed: the variable is initialized in its declaration.
13 var result = meta.Proceed();
14
15 Console.WriteLine( $"{meta.Target.Method.Name} returned {result}." );
16
17 return result;
18 }
19 catch ( Exception e )
20 {
21 Console.WriteLine( $"{meta.Target.Method.Name} failed: {e.Message}" );
22
23 throw;
24 }
25 }
26}
27
Source Code
1namespace Doc.LAMA0224.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.LAMA0224.Fixed;
4
5internal class Calculator
6{
7 [Log]
8 public int Add(int a, int b)
9 {
10 try
11 {
12 int result;
13 result = a + b;
14 Console.WriteLine($"Add returned {result}.");
15 return result;
16 }
17 catch (Exception e)
18 {
19 Console.WriteLine($"Add failed: {e.Message}");
20 throw;
21 }
22 }
23}
24