Open sandboxFocusImprove this doc

LAMA0518: The template of an explicit interface property has an extra accessor

Severity Error
Reported by Metalama.Framework
Message The aspect '<AspectType>' cannot implement the interface property '<InterfaceProperty>' in the type '<TargetType>' explicitly because the template '<TemplateMember>' has the '<AccessorKind>' accessor, which the interface property does not have. Remove the accessor from the template or implement the property implicitly.

Cause

When an aspect implements an interface with ImplementInterface, you can set the IsExplicit property of the [InterfaceMember] attribute to true to introduce an explicit implementation of the interface member.

In C#, an explicit implementation of a property must have exactly the accessors of the interface property. An implicit implementation can add accessors, for instance a public setter to a read-only interface property, but an explicit one can't.

Metalama reports LAMA0518 when the template of an explicit implementation has a get, set, or init accessor that the interface property doesn't declare. In the message, <AccessorKind> is the extra accessor.

In the following example, the IDescribable.Description property is read-only, but the template, which is an explicit implementation, also has a setter.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0518.Error;
5
6public interface IDescribable
7{
8    string Description { get; }
9}
10
11public class DescribableAttribute : TypeAspect
12{
13    public override void BuildAspect( IAspectBuilder<INamedType> builder )
14    {
15        builder.ImplementInterface( typeof(IDescribable) );
16    }
17
18    // Error: the interface property is read-only, but the template has a setter.
19    [InterfaceMember( IsExplicit = true )]
20    public string Description { get => meta.Target.Type.Name; set { } }
21}
22
1namespace Doc.LAMA0518.Error;
2
3[Describable]
Error LAMA0518: The aspect 'Describable' cannot implement the interface property 'IDescribable.Description' in the type 'Order' explicitly because the template 'DescribableAttribute.Description' has the 'set' accessor, which the interface property does not have. Remove the accessor from the template or implement the property implicitly.

4internal partial class Order
5{
6    public int Id { get; set; }
7}
8

Resolution

Do one of the following:

  • Remove the extra accessor from the template property. The following example uses this fix.
  • If the target type needs the extra accessor, implement the property implicitly: remove IsExplicit = true from the [InterfaceMember] attribute. The introduced property is then public.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0518.Fixed;
5
6public interface IDescribable
7{
8    string Description { get; }
9}
10
11public class DescribableAttribute : TypeAspect
12{
13    public override void BuildAspect( IAspectBuilder<INamedType> builder )
14    {
15        builder.ImplementInterface( typeof(IDescribable) );
16    }
17
18    // Fixed: the template has only the getter of the interface property.
19    [InterfaceMember( IsExplicit = true )]
20    public string Description { get => meta.Target.Type.Name; }
21}
22
Source Code
1namespace Doc.LAMA0518.Fixed;
2

3[Describable]
4internal partial class Order
5{
6    public int Id { get; set; }
7}
8
Transformed Code
1namespace Doc.LAMA0518.Fixed;
2
3[Describable]
4internal partial class Order : IDescribable
5{
6    public int Id { get; set; }
7
8    string IDescribable.Description
9    {
10        get
11        {
12            return "Order";
13        }
14    }
15}
16

See also