Open sandboxFocusImprove this doc

LAMA0232: A template uses a C# feature that's too recent

Severity Error
Reported by Metalama.Framework
Message Template code must be compatible with C# <LanguageVersion>, but this syntax requires a later version of C#.

Cause

When Metalama compiles a T# template, it checks that every syntax element of the template is available in the template language version. The placeholder of the message is this version. Metalama determines it as follows:

  • If the aspect project defines the MetalamaTemplateLanguageVersion MSBuild property, its value is the template language version. Aspect library authors set this property so that their templates can be used in projects built with an older version of C#.
  • Otherwise, the template language version is the LangVersion of the aspect project, limited to the highest version supported by the .NET SDK used for the build.

Metalama reports LAMA0232 on each syntax element of a template that requires a later version of C#, for instance a raw string literal (C# 11) in a template of a project where MetalamaTemplateLanguageVersion is 10.0. This check applies to the code of templates, not to other compile-time code such as BuildAspect.

In the following example, the Log aspect is defined in a referenced project, and its template contains a raw string literal, which requires C# 11. The project that uses the aspect is built with C# 10, so the template language version is also C# 10, and Metalama reports LAMA0232 on the literal. It also reports the warning LAMA0282 on the target method, and the C# compiler reports CS8936 for the same literal.

Source Code
1namespace Doc.LAMA0232.Error;
2
3public class Calculator


4{
5    // The [Log] aspect uses C# 11 features.
6    [Log]
    Warning LAMA0282: The aspect 'Log' uses features of C# 11.0, but it is used in a project built with C# 10.0. Consider specifying <LangVersion>11.0</LangVersion> in this project or removing newer language features from the template 'LogAttribute.OverrideMethod()' and then specifying <MetalamaTemplateLanguageVersion> in the aspect project.

7    public int Add( int a, int b ) => a + b;
8}
9
Transformed Code
1using System;
2
3namespace Doc.LAMA0232.Error;
4
5public class Calculator
6{
7    // The [Log] aspect uses C# 11 features.
8    [Log]
9    public int Add(int a, int b)
10    {
        Error CS8936: Feature 'raw string literals' is not available in C# 10.0. Please use language version 11.0 or greater.

11        var message = """Logged by the "Log" aspect.""";
12        Console.WriteLine(message);
13        return a + b;
14    }
15}
16
using Metalama.Framework.Aspects;
using System;

namespace Doc.LAMA0232.Error;

public class LogAttribute : OverrideMethodAspect
{
    public override dynamic? OverrideMethod()
    {
        // Raw string literals require C# 11, but the target project uses C# 10.
        var message = """Logged by the "Log" aspect.""";
        Console.WriteLine( message );

        return meta.Proceed();
    }
}

Resolution

Depending on your intent, do one of the following:

  • Rewrite the reported code using only features of the C# version given in the message. For instance, replace a raw string literal with a regular or verbatim string literal, as in the following example.

  • If your templates don't need to be used by projects built with an older version of C#, raise or remove the MetalamaTemplateLanguageVersion property in the aspect project:

    <PropertyGroup>
      <MetalamaTemplateLanguageVersion>12.0</MetalamaTemplateLanguageVersion>
    </PropertyGroup>
    
  • If the property isn't set, check the LangVersion property of the aspect project and the version of the .NET SDK used for the build, for instance in global.json.

Source Code
1namespace Doc.LAMA0232.Fixed;
2
3public class Calculator


4{
5    // The [Log] aspect now uses only C# 10 features.
6    [Log]
7    public int Add( int a, int b ) => a + b;
8}
9
Transformed Code
1using System;
2
3namespace Doc.LAMA0232.Fixed;
4
5public class Calculator
6{
7    // The [Log] aspect now uses only C# 10 features.
8    [Log]
9    public int Add(int a, int b)
10    {
11        var message = "Logged by the \"Log\" aspect.";
12        Console.WriteLine(message);
13        return a + b;
14    }
15}
16
using Metalama.Framework.Aspects;
using System;

namespace Doc.LAMA0232.Fixed;

public class LogAttribute : OverrideMethodAspect
{
    public override dynamic? OverrideMethod()
    {
        // A regular string literal is compatible with C# 10.
        var message = "Logged by the \"Log\" aspect.";
        Console.WriteLine( message );

        return meta.Proceed();
    }
}

See also