Open sandboxFocusImprove this doc

LAMA0221: The this keyword can't be used as a run-time expression

Severity Error
Reported by Metalama.Framework
Message Cannot use 'this' in expression '<Expression>' because a run-time expression is expected, and 'this' in a template is a compile-time keyword. Use 'meta.This' instead.

Cause

In a T# template, the this keyword refers to the instance of the aspect or template provider, which exists only at compile time. It doesn't refer to the object whose code the template generates. You can use this to access compile-time members of the aspect, but you can't use it as a value in the generated code.

Metalama reports LAMA0221 when a template uses this alone where a run-time expression is expected, for instance as an argument of a run-time method. In the message, <Expression> is the expression that contains this.

In the following example, the template passes this to the run-time AuditLog.Record method, intending to pass the target object.

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0221.Error;
4
5public class AuditAttribute : OverrideMethodAspect
6{
7    public override dynamic? OverrideMethod()
8    {
9        // Error: in a template, 'this' is the aspect instance, not the target object.
        Error LAMA0221: Cannot use 'this' in expression 'AuditLog.Record( this, meta.Target.Method.Name )' because a run-time expression is expected, and 'this' in a template is a compile-time keyword. Use 'meta.This' instead.

10        AuditLog.Record( this, meta.Target.Method.Name );
11
12        return meta.Proceed();
13    }
14}
15
1using System;
2
3namespace Doc.LAMA0221.Error;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder( string product ) { }
9}
10
11internal static class AuditLog
12{
13    public static void Record( object instance, string methodName )
14        => Console.WriteLine( $"{methodName} called on {instance}." );
15}
16

Resolution

Replace this with meta.This, which represents the this expression of the target code. meta.This is only available when the target member isn't static.

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0221.Fixed;
4
5public class AuditAttribute : OverrideMethodAspect
6{
7    public override dynamic? OverrideMethod()
8    {
9        // Fixed: meta.This represents the target object.
10        AuditLog.Record( meta.This, meta.Target.Method.Name );
11
12        return meta.Proceed();
13    }
14}
15
Source Code
1using System;
2
3namespace Doc.LAMA0221.Fixed;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder( string product ) { }
9}
10


11internal static class AuditLog

12{
13    public static void Record( object instance, string methodName )
14        => Console.WriteLine( $"{methodName} called on {instance}." );
15}
16
Transformed Code
1using System;
2
3namespace Doc.LAMA0221.Fixed;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder(string product)
9    {
10        AuditLog.Record(this, "PlaceOrder");
11    }
12}
13
14internal static class AuditLog
15{
16    public static void Record(object instance, string methodName)
17        => Console.WriteLine($"{methodName} called on {instance}.");
18}
19

See also