| Severity | Error |
| Reported by | Metalama.Framework |
| Message | '<Declaration>' cannot contain unsafe code because it is a template. |
Cause
A template is compiled into compile-time code that generates the run-time code, and Metalama doesn't support unsafe code in templates.
Metalama reports LAMA0249 when the declaration of a template has the unsafe modifier. This includes the template methods of aspects, such as OverrideMethod, methods marked with [TemplateAttribute], and members marked with [IntroduceAttribute]. The placeholder of the message is the template member.
When the unsafe modifier is on the aspect class itself, Metalama reports LAMA0248 instead.
In the following example, the OverrideMethod template of the Log aspect has the unsafe modifier.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0249.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 // Error: a template cannot be unsafe.
Error LAMA0249: 'LogAttribute.OverrideMethod()' cannot contain unsafe code because it is a template.
9 public override unsafe dynamic? OverrideMethod()
10 {
11 Console.WriteLine( $"Executing {meta.Target.Method}." );
12
13 return meta.Proceed();
14 }
15}
16
1namespace Doc.LAMA0249.Error;
2
3internal class Calculator
4{
5 [Log]
6 public int Add( int a, int b ) => a + b;
7}
8
Resolution
Remove the unsafe modifier from the template. Then do one of the following:
- Rewrite the template without pointers, for instance with Span or with the methods of the Unsafe and MemoryMarshal classes.
- If the generated code must contain unsafe code, build it as text with Parse or Parse. The target member or type must then provide the unsafe context, for instance by being declared
unsafe.
In the following example, the unsafe modifier is removed from the template.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0249.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 // Fixed: the template is not unsafe.
9 public override dynamic? OverrideMethod()
10 {
11 Console.WriteLine( $"Executing {meta.Target.Method}." );
12
13 return meta.Proceed();
14 }
15}
16
1namespace Doc.LAMA0249.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.LAMA0249.Fixed;
4
5internal class Calculator
6{
7 [Log]
8 public int Add(int a, int b)
9 {
10 Console.WriteLine("Executing Calculator.Add(int, int).");
11 return a + b;
12 }
13}
14