Open sandboxFocusImprove this doc

LAMA0519: An implicit interface implementation must be public

Severity Error
Reported by Metalama.Framework
Message The aspect '<AspectType>' cannot implicitly implement the interface '<InterfaceType>' with the member '<TemplateMember>' because this member or one of its accessors is not public. Make the member and its accessors public, or set the IsExplicit property of the [InterfaceMember] attribute to true.

Cause

When an aspect calls ImplementInterface, Metalama looks in the aspect class for members marked with the [InterfaceMember] attribute and uses them as templates for the members of the interface. By default, these members are introduced as implicit implementations, that is, as members of the target type that implement the interface by their name and signature.

In C#, an implicit interface implementation must be public. Metalama copies the accessibility of the template to the introduced member, so it reports LAMA0519 when the template is private, protected, or internal. For a property, every accessor that the interface requires must also be public: a public property with a private set accessor triggers the error when the interface declares a setter. An accessor that the template doesn't declare at all isn't checked here: Metalama reports it with LAMA0517 instead.

In the message, <InterfaceType> is the interface, and <TemplateMember> is the template member of the aspect class.

In the following example, the Describe template of the aspect is private.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0519.Error;
5
6public interface IDescribable
7{
8    string Describe();
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: an implicit interface implementation must be public.
19    [InterfaceMember]
20    private string Describe()
21    {
22        return $"This is an instance of {meta.Target.Type}.";
23    }
24}
25
1namespace Doc.LAMA0519.Error;
2
3[Describable]
Error LAMA0519: The aspect 'Describable' cannot implicitly implement the interface 'IDescribable' with the member 'DescribableAttribute.Describe()' because this member or one of its accessors is not public. Make the member and its accessors public, or set the IsExplicit property of the [InterfaceMember] attribute to true.

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

Resolution

Do one of the following:

  • Make the template member public, together with the accessors required by the interface. The following example shows this fix.
  • If you don't want the member to be part of the public surface of the target type, set the IsExplicit property of the attribute to true. Metalama then introduces an explicit interface implementation, which has no accessibility modifier.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0519.Fixed;
5
6public interface IDescribable
7{
8    string Describe();
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 member is public, so it can implement the interface implicitly.
19    [InterfaceMember]
20    public string Describe()
21    {
22        return $"This is an instance of {meta.Target.Type}.";
23    }
24}
25
Source Code
1namespace Doc.LAMA0519.Fixed;
2

3[Describable]
4internal partial class Order
5{
6    public int Id { get; set; }
7}
8
Transformed Code
1namespace Doc.LAMA0519.Fixed;
2
3[Describable]
4internal partial class Order : IDescribable
5{
6    public int Id { get; set; }
7
8    public string Describe()
9    {
10        return "This is an instance of Order.";
11    }
12}
13

See also