| Severity | Error |
| Reported by | Metalama.Framework |
| Message | Cannot cast the non-dynamic run-time expression '<Expression>' to IExpression. Use ExpressionFactory.Capture. |
Cause
The IExpression interface is the compile-time representation of a run-time expression. In a template, casting a dynamic expression to IExpression, for instance (IExpression) meta.Proceed(), is a special syntax that captures the expression. Metalama supports this syntax only for dynamic expressions, which can't be passed to ExpressionFactory.Capture because of a limitation of the C# language.
Metalama reports LAMA0286 when a template casts a run-time expression whose type isn't dynamic to IExpression. The C# cast compiles, but it can't work: the run-time value doesn't exist when the template runs, so it can't be converted to an IExpression object.
In the following example, the aspect casts the run-time local variable startTime, of type object, to IExpression.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0286.Error;
6
7public class LogStartTimeAttribute : OverrideMethodAspect
8{
9 public override dynamic? OverrideMethod()
10 {
11 object startTime = DateTime.Now;
12 IExpression startTimeExpression;
13
14 // Error: 'startTime' is a run-time expression that isn't dynamic, so it can't be cast to IExpression.
Error LAMA0286: Cannot cast the non-dynamic run-time expression 'startTime' to IExpression. Use ExpressionFactory.Capture.
15 startTimeExpression = (IExpression) startTime;
16
17 Console.WriteLine( $"{meta.Target.Method.Name} started at {startTimeExpression.Value}." );
18
19 return meta.Proceed();
20 }
21}
22
1namespace Doc.LAMA0286.Error;
2
3internal class OrderService
4{
5 [LogStartTime]
6 public void PlaceOrder( string product ) { }
7}
8
Resolution
Call ExpressionFactory.Capture instead of the cast. This method captures the syntax of a run-time expression into an IExpression without evaluating it.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using Metalama.Framework.Code.SyntaxBuilders;
4using System;
5
6namespace Doc.LAMA0286.Fixed;
7
8public class LogStartTimeAttribute : OverrideMethodAspect
9{
10 public override dynamic? OverrideMethod()
11 {
12 object startTime = DateTime.Now;
13 IExpression startTimeExpression;
14
15 // Fixed: ExpressionFactory.Capture creates an IExpression from a run-time expression.
16 startTimeExpression = ExpressionFactory.Capture( startTime );
17
18 Console.WriteLine( $"{meta.Target.Method.Name} started at {startTimeExpression.Value}." );
19
20 return meta.Proceed();
21 }
22}
23
1namespace Doc.LAMA0286.Fixed;
2
3internal class OrderService
4{
5 [LogStartTime]
6 public void PlaceOrder( string product ) { }
7}
8
1using System;
2
3namespace Doc.LAMA0286.Fixed;
4
5internal class OrderService
6{
7 [LogStartTime]
8 public void PlaceOrder(string product)
9 {
10 object startTime = DateTime.Now;
11 Console.WriteLine($"PlaceOrder started at {startTime}.");
12 }
13}
14