| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The template '<Template>' cannot be an extension method. To introduce an extension method, mark the first parameter of the template with the [This] attribute, or set the IParameterBuilder.IsThis property programmatically. |
Cause
Metalama reports LAMA0271 when a method marked as a template, for instance with [Template] or [Introduce], is a C# extension method, that is, when its first parameter has the this modifier. Templates don't support the this modifier on their parameters.
You typically get this error when you want an aspect to introduce an extension method into a static class. The this modifier doesn't belong in the template, because the template isn't the extension method: it only describes the method that Metalama introduces into the target class.
C# allows extension methods only in top-level static classes, and such a class can't be an aspect, a fabric, or a type implementing ITemplateProvider. Therefore, Metalama always reports LAMA0274 together with LAMA0271, as in the following example, where the PrintDetails template is an extension method of a static class.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0271.Error;
5
6[RunTimeOrCompileTime]
7internal static class ObjectExtensions
8{
9 // Error: a template cannot be an extension method.
10 [Template]
Error LAMA0274: The template 'ObjectExtensions.PrintDetails(object)' is contained in 'ObjectExtensions', which is not an aspect, a fabric, or a type implementing ITemplateProvider.
11 public static void PrintDetails( this object self )
12 {
13 Console.WriteLine( self );
14 }
15}
16
Resolution
Remove the this modifier from the first parameter of the template, and move the template to an aspect, a fabric, or a class implementing ITemplateProvider. Then, to make the introduced method an extension method, do one of the following:
- Mark the first parameter of the template with the ThisAttribute attribute. As C# requires for extension methods, the introduced method must be static, and the target type must be a static class.
- When you introduce the method programmatically, set the IsThis property of its first parameter to
truein thebuildMethoddelegate.
In the following example, the template is moved to an aspect, its parameter is marked with the [This] attribute, and the aspect is applied to the static class that receives the extension method.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0271.Fixed;
5
6public class ExtensionsAttribute : TypeAspect
7{
8 // Fixed: the [This] attribute makes the introduced method an extension method.
9 [Introduce]
10 public static void PrintDetails( [This] object self )
11 {
12 Console.WriteLine( self );
13 }
14}
15
1namespace Doc.LAMA0271.Fixed;
2
3[Extensions]
4internal static partial class ObjectExtensions
5{
6}
7
1using System;
2
3namespace Doc.LAMA0271.Fixed;
4
5[Extensions]
6internal static partial class ObjectExtensions
7{
8 public static void PrintDetails(this object self)
9 {
10 Console.WriteLine(self);
11 }
12}
13