Open sandboxFocusImprove this doc

LAMA0264: A compile-time template parameter can't have a run-time-only type

Severity Error
Reported by Metalama.Framework
Message The compile-time template parameter '<Parameter>' cannot have the run-time-only type '<Type>'.

Cause

A template method can have compile-time parameters, marked with the [CompileTime] attribute. The aspect passes their values when it adds the advice, and Metalama uses them while it expands the template, at compile time. For this reason, the value of a compile-time parameter must be of a type that exists at compile time: a compile-time-only type like IField, or a type that's both run-time and compile-time, like string or int.

Metalama reports LAMA0264 when the type of a compile-time template parameter is run-time-only. Typical cases are:

  • The parameter type is a compile-time template type parameter, or a type built from one, like T[] or List<T>. A compile-time type parameter stands for a type of the generated code, so its values only exist at run time.
  • The parameter type is a run-time type, for instance a class of the target project, or a type built from a run-time type parameter.

In the message, <Parameter> is the name of the parameter and <Type> is its type.

In the following example, the Log template has a compile-time type parameter T and a compile-time parameter message of type T.

1using Metalama.Framework.Advising;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5
6namespace Doc.LAMA0264.Error;
7
8public class AddLogMethodAttribute : TypeAspect
9{
10    public override void BuildAspect( IAspectBuilder<INamedType> builder )
11    {
12        builder.IntroduceMethod( nameof(this.Log), args: new { T = typeof(string) } );
13    }
14
15    [Template]
16    public void Log<[CompileTime] T>(
17        // Error: T stands for a run-time type, so the parameter cannot be compile-time.
        Error LAMA0264: The compile-time template parameter 'message' cannot have the run-time-only type 'T'.

18        [CompileTime] T message )
19    {
20        Console.WriteLine( $"{meta.Target.Type.Name}: {message}" );
21    }
22}
23
1namespace Doc.LAMA0264.Error;
2
3[AddLogMethod]
4internal partial class OrderService
5{
6    public void PlaceOrder( int productId ) { }
7}
8

Resolution

Depending on your intent, do one of the following:

  • If the value is only known at run time, remove the [CompileTime] attribute from the parameter. It becomes a run-time parameter: a parameter of the introduced method or, for an overriding template, a reference to a parameter of the overridden method.
  • If the value is known when the aspect adds the advice, change the parameter type to a type that's available at compile time, for instance string, a compile-time-only type, or a type marked with [RunTimeOrCompileTime].

In the following example, the [CompileTime] attribute is removed from the parameter, so the introduced Log method receives the message as a parameter of type string.

1using Metalama.Framework.Advising;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Code;
4using System;
5
6namespace Doc.LAMA0264.Fixed;
7
8public class AddLogMethodAttribute : TypeAspect
9{
10    public override void BuildAspect( IAspectBuilder<INamedType> builder )
11    {
12        builder.IntroduceMethod( nameof(this.Log), args: new { T = typeof(string) } );
13    }
14
15    [Template]
16    public void Log<[CompileTime] T>(
17        // Fixed: the parameter is run-time, so it becomes a parameter of the introduced method.
18        T message )
19    {
20        Console.WriteLine( $"{meta.Target.Type.Name}: {message}" );
21    }
22}
23
Source Code
1namespace Doc.LAMA0264.Fixed;
2


3[AddLogMethod]
4internal partial class OrderService
5{
6    public void PlaceOrder( int productId ) { }
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0264.Fixed;
4
5[AddLogMethod]
6internal partial class OrderService
7{
8    public void PlaceOrder(int productId) { }
9
10    public void Log(string message)
11    {
12        Console.WriteLine($"OrderService: {message}");
13    }
14}
15

See also