Open sandboxFocusImprove this doc

LAMA0253: A compile-time-only value can't be passed to a run-time method

Severity Error
Reported by Metalama.Framework
Message Compile-time-only type '<Type>' cannot be used in the invocation of run-time method '<Method>'.

Cause

Some types exist only at compile time, for instance the types of the code model like IMethod, IParameter, or INamedType, and the types marked with [CompileTime]. Their values describe the code being compiled and don't exist when the program runs.

When a template calls a run-time method, Metalama emits the call into the target code, so each argument must be a value that run-time code can receive. Metalama reports LAMA0253 when the type of an argument is compile-time-only. The first placeholder of the message is the type of the argument, and the second one is the invoked method, as written in the template.

In the following example, the aspect passes meta.Target.Method, an IMethod, to the run-time AuditLog.Write method.

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0253.Error;
4
5public class AuditAttribute : OverrideMethodAspect
6{
7    public override dynamic? OverrideMethod()
8    {
9        // Error: IMethod is a compile-time type, but AuditLog.Write is a run-time method.
        Error LAMA0253: Compile-time-only type 'IMethod' cannot be used in the invocation of run-time method 'AuditLog.Write'.

10        AuditLog.Write( meta.Target.Method );
11
12        return meta.Proceed();
13    }
14}
15
1using System;
2
3namespace Doc.LAMA0253.Error;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder( string productId, int quantity )
9    {
10        Console.WriteLine( $"Ordering {quantity} x {productId}." );
11    }
12}
13
14public static class AuditLog
15{
16    public static void Write( object operation ) => Console.WriteLine( $"Audit: {operation}" );
17}
18

Resolution

Pass a run-time value derived from the compile-time object instead of the object itself:

  • To pass a description of the declaration, use a string, for instance its Name property, as in the following example. Metalama evaluates the expression at compile time and emits the resulting string literal.
  • To pass the run-time value of a parameter, field, or property, use its Value property, for instance meta.Target.Parameters[0].Value.
  • To pass a reflection object, use a conversion method of the code model, such as ToMethodInfo() or ToType().

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0253.Fixed;
4
5public class AuditAttribute : OverrideMethodAspect
6{
7    public override dynamic? OverrideMethod()
8    {
9        // Fixed: the name of the method is a string, which can be passed to run-time code.
10        AuditLog.Write( meta.Target.Method.Name );
11
12        return meta.Proceed();
13    }
14}
15
Source Code
1using System;
2
3namespace Doc.LAMA0253.Fixed;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder( string productId, int quantity )
9    {
10        Console.WriteLine( $"Ordering {quantity} x {productId}." );
11    }
12}

13
14public static class AuditLog
15{
16    public static void Write( object operation ) => Console.WriteLine( $"Audit: {operation}" );
17}
18
Transformed Code
1using System;
2
3namespace Doc.LAMA0253.Fixed;
4
5internal class OrderService
6{
7    [Audit]
8    public void PlaceOrder(string productId, int quantity)
9    {
10        AuditLog.Write("PlaceOrder");
11        Console.WriteLine($"Ordering {quantity} x {productId}.");
12    }
13}
14
15public static class AuditLog
16{
17    public static void Write(object operation) => Console.WriteLine($"Audit: {operation}");
18}
19

See also