| Severity | Error |
| Reported by | Metalama.Framework |
| Message | Cannot reference 'this' in an advice applied to <TargetKind> '<TargetDeclaration>' because <Explanation>. |
Cause
In a template, This represents the current instance of the target type, and Metalama generates a this expression for it. Some code model operations also generate this implicitly, for instance when the template invokes an instance member of the target type without specifying the receiver.
A static member has no current instance. Metalama reports LAMA0114 when it expands a template that needs this while the advice is applied to a static member, for instance a static method or the static constructor. The last part of the message explains why no instance is available. Metalama detects the problem only when it expands the template for a given target, so the same aspect works on instance members and fails on static ones.
In the following example, the Trace aspect prints meta.This. It works on the instance method Add, but fails on the static method Multiply.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0114.Error;
5
6public class TraceAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // meta.This requires an instance method.
11 Console.WriteLine( $"Executing {meta.Target.Method.Name} on {meta.This}." );
12
13 return meta.Proceed();
14 }
15}
16
1namespace Doc.LAMA0114.Error;
2
3internal class Calculator
4{
5 private int _total;
6
7 [Trace]
8 public int Add( int value ) => this._total += value;
9
10 // Error: the template of [Trace] uses meta.This, but this method is static.
11 [Trace]
Error LAMA0114: Cannot reference 'this' in an advice applied to method 'Calculator.Multiply(int, int)' because the target method is static.
12 public static int Multiply( int a, int b ) => a * b;
13}
14
Resolution
Depending on your intent, do one of the following:
- Make the template handle static members: test
meta.Target.Method.IsStatic, or theIsStaticproperty of the relevant declaration, in a compile-timeifstatement, and use meta.This only in the branch for instance members. The following example uses this approach. - If the aspect can't work without an instance, add the MustNotBeStatic condition to the aspect's
BuildEligibilitymethod. Metalama then reports that the aspect isn't eligible on static members, and fabrics can skip them. - Remove the aspect from the static member.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0114.Fixed;
5
6public class TraceAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 // Use meta.This only when the target method is not static.
11 if ( meta.Target.Method.IsStatic )
12 {
13 Console.WriteLine( $"Executing {meta.Target.Method.Name}." );
14 }
15 else
16 {
17 Console.WriteLine( $"Executing {meta.Target.Method.Name} on {meta.This}." );
18 }
19
20 return meta.Proceed();
21 }
22}
23
1namespace Doc.LAMA0114.Fixed;
2
3internal class Calculator
4{
5 private int _total;
6
7 [Trace]
8 public int Add( int value ) => this._total += value;
9
10 // Fixed: the template of [Trace] no longer uses meta.This on static methods.
11 [Trace]
12 public static int Multiply( int a, int b ) => a * b;
13}
14
1using System;
2
3namespace Doc.LAMA0114.Fixed;
4
5internal class Calculator
6{
7 private int _total;
8
9 [Trace]
10 public int Add(int value)
11 {
12 Console.WriteLine($"Executing Add on {this}.");
13 return this._total += value;
14 }
15
16 // Fixed: the template of [Trace] no longer uses meta.This on static methods.
17 [Trace]
18 public static int Multiply(int a, int b)
19 {
20 Console.WriteLine("Executing Multiply.");
21 return a * b;
22 }
23}
24