Open sandboxFocusImprove this doc

LAMA0242: The type of an expression conflicts with the scope of its sub-expression

Severity Error
Reported by Metalama.Framework
Message Execution scope mismatch in the expression '<ParentExpression>': the type of the expression is <ParentScope>, but the sub-expression '<ChildExpression>' is <ChildScope>.

Cause

In a T# template, Metalama classifies every expression as either compile-time, which it evaluates while generating the code, or run-time, which it copies into the generated code. The scope of an expression depends on its sub-expressions, but also on its type: an expression of a run-time-only type, such as a type defined in your project, can only exist at run time, while an expression of a compile-time type, such as IParameter, can only exist at compile time.

Metalama reports LAMA0242 when the sub-expressions of an expression agree on a scope, but the type of the expression requires the other scope. The message gives the scope of the type and the sub-expression that conflicts with it. This typically happens when you apply the as operator to a compile-time object, such as an IParameter, while you meant to apply it to the run-time value that the object represents.

In the following example, the aspect checks whether the first argument of the method is a Customer, but it applies the as operator to the compile-time parameter instead of the argument value.

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0242.Error;
4
5public class LogCustomerAttribute : OverrideMethodAspect
6{
7    public override dynamic? OverrideMethod()
8    {
9        // Error: the run-time 'as' operator is applied to the compile-time IParameter, not to the argument value.
        Error LAMA0242: Execution scope mismatch in the expression 'meta.Target.Parameters[0] as Customer': the type of the expression is run-time, but the sub-expression 'meta.Target.Parameters[0]' is compile-time.

10        var customer = meta.Target.Parameters[0] as Customer;
11
12        return meta.Proceed();
13    }
14}
15
1namespace Doc.LAMA0242.Error;
2
3public class Person
4{
5    public string Name { get; set; } = "";
6}
7
8public class Customer : Person
9{
10    public int LoyaltyPoints { get; set; }
11}
12
13internal class OrderService
14{
15    [LogCustomer]
16    public void PlaceOrder( Person buyer, int quantity ) { }
17}
18

Resolution

Make the sub-expression match the scope of the expression type. To work with the run-time value of a parameter, field, or property, use its Value property, which is a run-time expression of type dynamic. The following example applies the as operator to meta.Target.Parameters[0].Value.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0242.Fixed;
5
6public class LogCustomerAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        // Fixed: the 'as' operator is applied to the run-time value of the parameter.
11        var customer = meta.Target.Parameters[0].Value as Customer;
12
13        if ( customer != null )
14        {
15            Console.WriteLine( $"Customer {customer.Name} has {customer.LoyaltyPoints} loyalty points." );
16        }
17
18        return meta.Proceed();
19    }
20}
21
Source Code
1namespace Doc.LAMA0242.Fixed;
2


3public class Person
4{
5    public string Name { get; set; } = "";
6}
7
8public class Customer : Person
9{
10    public int LoyaltyPoints { get; set; }
11}
12
13internal class OrderService
14{
15    [LogCustomer]
16    public void PlaceOrder( Person buyer, int quantity ) { }
17}
18
Transformed Code
1using System;
2
3namespace Doc.LAMA0242.Fixed;
4
5public class Person
6{
7    public string Name { get; set; } = "";
8}
9
10public class Customer : Person
11{
12    public int LoyaltyPoints { get; set; }
13}
14
15internal class OrderService
16{
17    [LogCustomer]
18    public void PlaceOrder(Person buyer, int quantity)
19    {
20        var customer = buyer as Customer;
21        if (customer != null)
22        {
23            Console.WriteLine($"Customer {customer.Name} has {customer.LoyaltyPoints} loyalty points.");
24        }
25    }
26}
27

See also