Open sandboxFocusImprove this doc

LAMA0258: The declaration can't be a template

Severity Error
Reported by Metalama.Framework
Message '<Declaration>' cannot be a template because constructors, finalizers, operators, and conversion operators are not supported as templates. Introduce the member programmatically from a template method instead.

Cause

You can introduce fields, properties, events, and methods declaratively by marking a member of the aspect with [IntroduceAttribute], or turn such a member into a template with [TemplateAttribute]. Finalizers, user-defined operators, and conversion operators can't be templates, because their declaration in the aspect class is bound to the aspect type itself. The same rule applies to constructors.

Metalama reports LAMA0258 when one of these members carries a template attribute.

In the following example, the aspect tries to introduce a finalizer declaratively.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0258.Error;
5
6public class TrackFinalizationAttribute : TypeAspect
7{
8    // Error: a finalizer can't be a template.
9    [Introduce]
    Error LAMA0258: 'TrackFinalizationAttribute.~TrackFinalizationAttribute()' cannot be a template because constructors, finalizers, operators, and conversion operators are not supported as templates. Introduce the member programmatically from a template method instead.

10    ~TrackFinalizationAttribute()
11    {
12        Console.WriteLine( "Finalizing the object." );
13    }
14}
15
1namespace Doc.LAMA0258.Error;
2
3[TrackFinalization]
4internal class FileHandle { }
5

Resolution

Write the body of the member in a regular method marked with [TemplateAttribute], and introduce the member programmatically from BuildAspect with the matching advice method: IntroduceFinalizer, IntroduceUnaryOperator, IntroduceBinaryOperator, IntroduceConversionOperator, or IntroduceConstructor.

The following example introduces the finalizer with IntroduceFinalizer.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0258.Fixed;
6
7public class TrackFinalizationAttribute : TypeAspect
8{
9    public override void BuildAspect( IAspectBuilder<INamedType> builder )
10    {
11        // Fixed: the finalizer is introduced programmatically from a template method.
12        builder.IntroduceFinalizer( nameof(this.FinalizerTemplate) );
13    }
14
15    [Template]
16    private void FinalizerTemplate()
17    {
18        Console.WriteLine( "Finalizing the object." );
19    }
20}
21
Source Code
1namespace Doc.LAMA0258.Fixed;
2


3[TrackFinalization]
4internal class FileHandle { }
5
Transformed Code
1using System;
2
3namespace Doc.LAMA0258.Fixed;
4
5[TrackFinalization]
6internal class FileHandle
7{
8    ~FileHandle()
9    {
10        Console.WriteLine("Finalizing the object.");
11    }
12}
13

See also