Open sandboxFocusImprove this doc

LAMA0101: The C# language feature isn't supported in a template

Severity Error
Reported by Metalama.Framework
Message '<Feature>' is not supported in a template.

Cause

T# templates support most of the C# language, but a few constructs can't be split into compile-time and run-time parts. Metalama reports LAMA0101 when a template contains one of the following constructs, named by the placeholder of the message:

  • a LINQ query expression (from ... select ...), reported as LINQ;
  • a goto statement;
  • an unsafe block;
  • a tuple deconstruction that mixes var declarations with explicitly typed declarations or existing variables.

The LINQ method syntax, for example Select and Where with lambdas, is supported. Only the query syntax isn't.

In the following example, the aspect uses a LINQ query to get the names of the parameters of the target method.

1using Metalama.Framework.Aspects;
2using System;
3using System.Linq;
4
5namespace Doc.LAMA0101.Error;
6
7public class LogEntryAttribute : OverrideMethodAspect
8{
9    public override dynamic? OverrideMethod()
10    {
11        // Error: LINQ query syntax isn't supported in a template.
        Error LAMA0101: 'LINQ' is not supported in a template.

12        var parameterNames = from parameter in meta.Target.Parameters
13                             select parameter.Name;
14
15        Console.WriteLine( $"Entering {meta.Target.Method.Name}( {string.Join( ", ", parameterNames )} )." );
16
17        return meta.Proceed();
18    }
19}
20
1namespace Doc.LAMA0101.Error;
2
3internal class CustomerService
4{
5    [LogEntry]
6    public void Register( string name, string email ) { }
7}
8

Resolution

Rewrite the code without the unsupported construct:

  • Replace a LINQ query expression with the equivalent LINQ method calls, as in the following example.
  • Replace goto with structured statements such as loops, break, or return.
  • Move unsafe code to a run-time helper method and call it from the template.
  • In a tuple deconstruction, use var for all elements, or declare the variables before the deconstruction.

1using Metalama.Framework.Aspects;
2using System;
3using System.Linq;
4
5namespace Doc.LAMA0101.Fixed;
6
7public class LogEntryAttribute : OverrideMethodAspect
8{
9    public override dynamic? OverrideMethod()
10    {
11        // Fixed: the LINQ method syntax is supported in a template.
12        var parameterNames = meta.Target.Parameters.Select( parameter => parameter.Name );
13
14        Console.WriteLine( $"Entering {meta.Target.Method.Name}( {string.Join( ", ", parameterNames )} )." );
15
16        return meta.Proceed();
17    }
18}
19
Source Code
1namespace Doc.LAMA0101.Fixed;
2


3internal class CustomerService
4{
5    [LogEntry]
6    public void Register( string name, string email ) { }
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0101.Fixed;
4
5internal class CustomerService
6{
7    [LogEntry]
8    public void Register(string name, string email)
9    {
10        Console.WriteLine("Entering Register( name, email ).");
11    }
12}
13

See also