| 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[]orList<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
1namespace Doc.LAMA0264.Fixed;
2
3[AddLogMethod]
4internal partial class OrderService
5{
6 public void PlaceOrder( int productId ) { }
7}
8
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