Open sandboxFocusImprove this doc

LAMA0508: An introduced member can't be both static and sealed

Severity Error
Reported by Metalama.Framework
Message The aspect '<AspectType>' cannot introduce sealed member '<Member>' because it is also static.

Cause

In C#, the sealed modifier on a member prevents derived classes from overriding it further. It only makes sense on an instance member that overrides a virtual member. A static member can't be overridden, so it can't be sealed. Metalama reports LAMA0508 when an aspect introduces a member that is both static and sealed.

The introduced member is static when the introduction scope is IntroductionScope.Static, or when the scope is the default one and the template is static. It's sealed when the IsSealed property of the custom attribute is set, or when the build action sets the IsSealed property.

In the following example, the Describe aspect introduces the GetTypeDescription method from a static template, and its build action marks the method as sealed.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0508.Error;
5
6public class DescribeAttribute : TypeAspect
7{
8    public override void BuildAspect( IAspectBuilder<INamedType> builder )
9    {
10        // A static member cannot be sealed.
11        builder.IntroduceMethod(
12            nameof(GetTypeDescription),
13            buildMethod: method => method.IsSealed = true );
14    }
15
16    [Template]
17    public static string GetTypeDescription()
18    {
19        return meta.Target.Type.Name;
20    }
21}
22
1namespace Doc.LAMA0508.Error;
2
3// Error: the [Describe] aspect introduces a method that is both static and sealed.
4[Describe]
Error LAMA0508: The aspect 'Describe' cannot introduce sealed member 'Product.GetTypeDescription()' because it is also static.

5public partial class Product
6{
7    public string? Name { get; set; }
8}
9

Resolution

Decide whether the introduced member must be static or sealed:

  • If the member must be static, don't set IsSealed in the custom attribute or in the build action. This is the fix shown in the example below.
  • If the member overrides a virtual member of a base class and you want to prevent further overrides, introduce it as an instance member: use a non-static template, or pass IntroductionScope.Instance as the scope.

In the following example, the aspect introduces the static method without marking it as sealed.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0508.Fixed;
5
6public class DescribeAttribute : TypeAspect
7{
8    public override void BuildAspect( IAspectBuilder<INamedType> builder )
9    {
10        // The static member is not marked as sealed.
11        builder.IntroduceMethod( nameof(GetTypeDescription) );
12    }
13
14    [Template]
15    public static string GetTypeDescription()
16    {
17        return meta.Target.Type.Name;
18    }
19}
20
Source Code
1namespace Doc.LAMA0508.Fixed;
2

3// Fixed: the [Describe] aspect introduces a static method that is not sealed.
4[Describe]
5public partial class Product
6{
7    public string? Name { get; set; }
8}
9
Transformed Code
1namespace Doc.LAMA0508.Fixed;
2
3// Fixed: the [Describe] aspect introduces a static method that is not sealed.
4[Describe]
5public partial class Product
6{
7    public string? Name { get; set; }
8
9    public static string GetTypeDescription()
10    {
11        return "Product";
12    }
13}
14

See also