Open sandboxFocusImprove this doc

LAMA0246: A local function in a template can't use dynamic in its signature

Severity Error
Reported by Metalama.Framework
Message The return type or a parameter type of a local function in a template cannot be dynamic. Use a specific type, for instance 'object', instead.

Cause

In a T# template, dynamic stands for a type that Metalama resolves when it expands the template, for instance the return type of the target method. A local function declared in a template is copied to the target code, but Metalama doesn't support dynamic in its signature.

Metalama reports LAMA0246 when dynamic appears in the return type or in a parameter type of a local function declared in a template. The body of the local function can still use dynamic expressions, like meta.Proceed().

In the following example, the local function PrintResult has a dynamic parameter.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0246.Error;
5
6public class LogResultAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Error: the parameter of a local function cannot be dynamic.
        Error LAMA0246: The return type or a parameter type of a local function in a template cannot be dynamic. Use a specific type, for instance 'object', instead.

11        void PrintResult( dynamic? value )
12        {
13            Console.WriteLine( $"Returning {value}." );
14        }
15
16        var result = meta.Proceed();
17        PrintResult( result );
18
19        return result;
20    }
21}
22
1namespace Doc.LAMA0246.Error;
2
3internal class Calculator
4{
5    [LogResult]
6    public int Add( int a, int b ) => a + b;
7}
8

Resolution

Use a specific type in the signature of the local function:

  • Use object? when the local function must accept or return values of any type, as in the following example.
  • Use the actual type when the template is designed for a specific return type or parameter type, for instance bool.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0246.Fixed;
5
6public class LogResultAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Fixed: the parameter has a specific type.
11        void PrintResult( object? value )
12        {
13            Console.WriteLine( $"Returning {value}." );
14        }
15
16        var result = meta.Proceed();
17        PrintResult( result );
18
19        return result;
20    }
21}
22
Source Code
1namespace Doc.LAMA0246.Fixed;
2


3internal class Calculator
4{
5    [LogResult]
6    public int Add( int a, int b ) => a + b;
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0246.Fixed;
4
5internal class Calculator
6{
7    [LogResult]
8    public int Add(int a, int b)
9    {
10        void PrintResult(object? value)
11        {
12            Console.WriteLine($"Returning {value}.");
13        }
14
15        int result;
16        result = a + b;
17        PrintResult(result);
18        return result;
19    }
20}
21

See also