Open sandboxFocusImprove this doc

LAMA0255: A run-time expression can't be cast to a compile-time type

Severity Error
Reported by Metalama.Framework
Message Cannot cast the run-time expression '<Expression>' to the compile-time type '<Type>'.

Cause

In a T# template, a run-time expression represents code that's evaluated when the program runs, while a value of a compile-time-only type, such as IParameter or IMethod, exists only while Metalama compiles the code. A cast can't turn one into the other.

Metalama reports LAMA0255 when a template casts an expression whose value is run-time to a compile-time-only type. The most common cause is a confusion between a declaration of the code model and its run-time value: for instance, the Value property of an IParameter represents the value of the parameter at run time, not the parameter itself. A cast to IExpression is a different case, reported as LAMA0286.

In the following example, the aspect tries to get the first parameter by casting the run-time value of this parameter back to IParameter.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0255.Error;
5
6public class LogFirstParameterAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Error: Value is the run-time value of the parameter, so it cannot be cast to IParameter.
        Error LAMA0255: Cannot cast the run-time expression 'meta.Target.Parameters[0].Value!' to the compile-time type 'IParameter'.

11        _ = (IParameter) meta.Target.Parameters[0].Value!;
12
13        return meta.Proceed();
14    }
15}
16
1namespace Doc.LAMA0255.Error;
2
3internal class CustomerRepository
4{
5    [LogFirstParameter]
6    public string? FindCustomerId( string name ) => null;
7}
8

Resolution

Read compile-time information from the compile-time code model, for instance from meta.Target.Parameters, and use the Value property only when you need the run-time value. In the following example, the aspect reads the IParameter directly from meta.Target.Parameters and logs its name.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0255.Fixed;
6
7public class LogFirstParameterAttribute : OverrideMethodAspect
8{
9    public override dynamic? OverrideMethod()
10    {
11        // Fixed: the IParameter is read from the compile-time code model.
12        IParameter parameter = meta.Target.Parameters[0];
13        Console.WriteLine( parameter.Name );
14
15        return meta.Proceed();
16    }
17}
18
Source Code
1namespace Doc.LAMA0255.Fixed;
2


3internal class CustomerRepository
4{
5    [LogFirstParameter]
6    public string? FindCustomerId( string name ) => null;
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0255.Fixed;
4
5internal class CustomerRepository
6{
7    [LogFirstParameter]
8    public string? FindCustomerId(string name)
9    {
10        Console.WriteLine("name");
11        return null;
12    }
13}
14

See also