| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The template '<ReferencedDeclaration>' cannot be referenced from the template '<ReferencingDeclaration>' because it is not a method. A template can only call other templates that are methods. |
Cause
A T# template can reuse code from another template by calling it. These auxiliary templates must be methods marked with the [Template] attribute. Templates of other kinds, such as properties, fields, or events marked with [Template], exist to be introduced into the target type. They can't be referenced from another template.
Metalama reports LAMA0220 when a template references a template that isn't a method. In the message, <ReferencedDeclaration> is the referenced template and <ReferencingDeclaration> is the template that contains the reference.
In the following example, the OverrideMethod template uses the EntryMessage template property to compute a message.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0220.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Error: 'EntryMessage' is a template property, but a template can only call template methods.
Error LAMA0220: The template 'LogAttribute.EntryMessage' cannot be referenced from the template 'LogAttribute.OverrideMethod()' because it is not a method. A template can only call other templates that are methods.
11 Console.WriteLine( EntryMessage );
12
13 return meta.Proceed();
14 }
15
16 [Template]
17 private string EntryMessage => $"Entering {meta.Target.Method}.";
18}
19
1namespace Doc.LAMA0220.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Turn the reusable code into an auxiliary template method and call it as a stand-alone statement. An auxiliary template call can't be part of an expression, so move the whole statement into the auxiliary template, as in the following example.
If you only need to compute a value at compile time, use a regular compile-time method or property, without the [Template] attribute, instead.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0220.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Fixed: the reusable code is a template method, called as a stand-alone statement.
11 LogEntry();
12
13 return meta.Proceed();
14 }
15
16 [Template]
17 private void LogEntry()
18 {
19 Console.WriteLine( $"Entering {meta.Target.Method}." );
20 }
21}
22
1namespace Doc.LAMA0220.Fixed;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
1using System;
2
3namespace Doc.LAMA0220.Fixed;
4
5internal class Calculator
6{
7 [Log]
8 public int Add(int a, int b)
9 {
10 Console.WriteLine("Entering Calculator.Add(int, int).");
11 return a + b;
12 }
13}
14