| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The anonymous type '<AnonymousType>' cannot be used in both run-time and compile-time code in the same template. Change the property names or types of one of the anonymous objects, or use a named type instead. |
Cause
In a T# template, an anonymous object is normally run-time: Metalama copies the new { ... } expression into the target code. It's compile-time only when it appears in a compile-time context, for instance in the argument of meta.CompileTime(...) or in a lambda passed to a compile-time LINQ method.
The C# compiler gives the same anonymous type to all anonymous objects of a compilation that have the same property names, in the same order, with the same types. Metalama assigns a single scope to each anonymous type of a template, so it reports LAMA0269 when it finds the same anonymous type created once in run-time code and once in compile-time code. The <AnonymousType> placeholder shows the anonymous type, for instance <anonymous type: string Name>.
In the following example, the aspect creates a run-time anonymous object with a string property named Name, then a compile-time anonymous object with the same shape.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0269.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // This anonymous object is created at run time, in the target code.
11 var entry = new { Name = "Calculator" };
12 Console.WriteLine( entry );
13
14 // Error: the same anonymous type, with a single string property named Name, is created at compile time.
Error LAMA0269: The anonymous type '<anonymous type: string Name>' cannot be used in both run-time and compile-time code in the same template. Change the property names or types of one of the anonymous objects, or use a named type instead.
15 var target = meta.CompileTime( new { Name = meta.Target.Method.Name } );
16
17 return meta.Proceed();
18 }
19}
20
1namespace Doc.LAMA0269.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Make sure that the run-time and the compile-time anonymous objects have different anonymous types:
- Rename a property of one of the anonymous objects, or change its type, as in the following example.
- Use a named type instead of a compile-time anonymous object, for instance a class or a record marked with [CompileTime].
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0269.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // This anonymous object is created at run time, in the target code.
11 var entry = new { Name = "Calculator" };
12 Console.WriteLine( entry );
13
14 // Fixed: the compile-time anonymous object has a different property name, so it has a different anonymous type.
15 var target = meta.CompileTime( new { MethodName = meta.Target.Method.Name } );
16
17 return meta.Proceed();
18 }
19}
20
1namespace Doc.LAMA0269.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.LAMA0269.Fixed;
4
5internal class Calculator
6{
7 [Log]
8 public int Add(int a, int b)
9 {
10 var entry = new
11 {
12 Name = "Calculator"
13 };
14 Console.WriteLine(entry);
15 return a + b;
16 }
17}
18