Open sandboxFocusImprove this doc

LAMA0224: A dynamic local variable must be initialized

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 try block, as shown in the following example.
  • Initialize the variable with a dynamic expression that gives it the right type, for instance meta.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 Value property 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

See also