Open sandboxFocusImprove this doc

LAMA0251: A dynamic variable must be initialized with a dynamic expression

Severity Error
Reported by Metalama.Framework
Message The variable '<Variable>' is declared as 'dynamic', so it must be initialized with an expression of type 'dynamic'. Declare the variable with 'var' or with a non-dynamic type.

Cause

In a T# template, dynamic stands for a run-time type that's only known when Metalama expands the template. Metalama infers the actual type of a dynamic local variable from its initializer, which must itself be a dynamic expression, for instance meta.Proceed(), the Value property of a parameter, or meta.Default( type ).

Metalama reports LAMA0251 when a template declares a local variable of type dynamic and initializes it with an expression of another type, for instance a literal, a compile-time value such as meta.Target.Method.Name, or an expression cast to a non-dynamic type. It's also reported when a foreach statement declares its iteration variable as dynamic but iterates over a collection that isn't dynamic, such as meta.Target.Parameters. The placeholder of the message is the name of the variable.

In the following example, the aspect declares methodName as dynamic, but initializes it with the name of the target method, which is a compile-time string.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0251.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Error: 'methodName' is dynamic, but the method name is a compile-time string.
        Error LAMA0251: The variable 'methodName' is declared as 'dynamic', so it must be initialized with an expression of type 'dynamic'. Declare the variable with 'var' or with a non-dynamic type.

11        dynamic methodName = meta.Target.Method.Name;
12        Console.WriteLine( $"Entering {methodName}." );
13
14        return meta.Proceed();
15    }
16}
17
1namespace Doc.LAMA0251.Error;
2
3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8

Resolution

Declare the variable with var or with its actual type instead of dynamic. When the initializer is a compile-time value, the variable becomes a compile-time variable, and Metalama inserts its value in the generated code, as shown in the following example.

If you need a run-time variable of a type that's only known at compile time, initialize it with a dynamic expression. In a foreach statement over a compile-time collection, declare the iteration variable with var.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0251.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Fixed: 'var' makes 'methodName' a compile-time variable.
11        var methodName = meta.Target.Method.Name;
12        Console.WriteLine( $"Entering {methodName}." );
13
14        return meta.Proceed();
15    }
16}
17
Source Code
1namespace Doc.LAMA0251.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.LAMA0251.Fixed;
4
5internal class Calculator
6{
7    [Log]
8    public int Add(int a, int b)
9    {
10        Console.WriteLine("Entering Add.");
11        return a + b;
12    }
13}
14

See also