Open sandboxFocusImprove this doc

LAMA0244: The type and its base type have incompatible scopes

Severity Error
Reported by Metalama.Framework
Message Execution scope mismatch: the type '<Type>' is <Scope>, but its base type or interface '<BaseType>' is <BaseScope>.

Cause

Metalama assigns an execution scope to every type. A compile-time type, such as a class marked with CompileTimeAttribute, exists only while Metalama compiles the project. A run-time type, such as an ordinary class or interface of your project, exists only in the compiled program. Types marked with RunTimeOrCompileTimeAttribute, and many system types like IDisposable, exist in both.

A type can't derive from, or implement, a type that doesn't exist in its own scope. Metalama reports LAMA0244 on the base list of a type when one of its base types or interfaces has an incompatible scope, for instance:

  • a compile-time class that derives from a run-time class or implements a run-time interface;
  • a run-time class that derives from a compile-time-only class.

The message gives the scope of the type and the scope of the offending base type or interface.

In the following example, the compile-time class UpperCaseNameFormatter, used by the Log aspect, implements the interface INameFormatter, which is a run-time interface because it has no scope attribute.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0244.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        var name = new UpperCaseNameFormatter().Format( meta.Target.Method.Name );
11        Console.WriteLine( $"Executing {name}." );
12
13        return meta.Proceed();
14    }
15}
16
1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0244.Error;
4
5// A run-time interface, because it has no scope attribute.
6public interface INameFormatter
7{
8    string Format( string name );
9}
10
11// Error: a compile-time class cannot implement the run-time interface 'INameFormatter'.
12[CompileTime]
Error LAMA0244: Execution scope mismatch: the type 'UpperCaseNameFormatter' is compile-time, but its base type or interface 'INameFormatter' is run-time.

13public class UpperCaseNameFormatter : INameFormatter
14{
15    public string Format( string name ) => name.ToUpperInvariant();
16}
17
18internal class Calculator
19{
20    [Log]
21    public int Add( int a, int b ) => a + b;
22}
23

Resolution

Make the scopes compatible:

  • If the base type or interface only uses types that are available at compile time, mark it with [RunTimeOrCompileTime], as in the following example, so that both run-time and compile-time types can use it.
  • Otherwise, remove the base type or interface from the compile-time type, or split the type into a run-time type and a compile-time type.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0244.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        var name = new UpperCaseNameFormatter().Format( meta.Target.Method.Name );
11        Console.WriteLine( $"Executing {name}." );
12
13        return meta.Proceed();
14    }
15}
16
Source Code
1using Metalama.Framework.Aspects;
2

3namespace Doc.LAMA0244.Fixed;
4
5// Fixed: [RunTimeOrCompileTime] makes the interface available at compile time.
6[RunTimeOrCompileTime]
7public interface INameFormatter
8{
9    string Format( string name );
10}
11
12// The compile-time class can now implement the interface.
13[CompileTime]
14public class UpperCaseNameFormatter : INameFormatter




15{
16    public string Format( string name ) => name.ToUpperInvariant();
17}
18
19internal class Calculator
20{




21    [Log]
22    public int Add( int a, int b ) => a + b;
23}
24
Transformed Code
1using System;
2using Metalama.Framework.Aspects;
3
4namespace Doc.LAMA0244.Fixed;
5
6// Fixed: [RunTimeOrCompileTime] makes the interface available at compile time.
7[RunTimeOrCompileTime]
8public interface INameFormatter
9{
10    string Format(string name);
11}
12
13// The compile-time class can now implement the interface.
14
15#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
16
17
18[CompileTime]
19public class UpperCaseNameFormatter : INameFormatter
20{
21    public string Format(string name) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
22}
23
24#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
25
26
27
28internal class Calculator
29{
30    [Log]
31    public int Add(int a, int b)
32    {
33        Console.WriteLine("Executing ADD.");
34        return a + b;
35    }
36}
37

See also