Open sandboxFocusImprove this doc

LAMA0500: The introduced member already exists

Severity Error
Reported by Metalama.Framework
Message The aspect '<AspectType>' cannot introduce member '<Member>' into type '<TargetType>' because it is already defined in type '<DeclaringType>'. Use a different OverrideStrategy or skip the member.

Cause

When an aspect introduces a member, such as a method, property, field, event, indexer, constructor or finalizer, Metalama first checks whether the target type, or one of its visible base types, already defines a member with the same name, or the same signature for methods. What happens then depends on the OverrideStrategy of the advice. The default strategy, Fail, reports LAMA0500 and doesn't introduce the member.

In the message, <Member> is the member that the aspect tries to introduce, <TargetType> is the target type, and <DeclaringType> is the type that already defines the member: the target type itself or one of its base types.

In the following example, the Resettable aspect introduces a Reset method into the ShoppingCart class, but the class already has a Reset method.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0500.Error;
5
6public class ResettableAttribute : TypeAspect
7{
8    [Introduce]
9    public void Reset()
10    {
11        Console.WriteLine( "Resetting the object." );
12        meta.Proceed();
13    }
14}
15
1using System.Collections.Generic;
2
3namespace Doc.LAMA0500.Error;
4
5// Error: the aspect introduces a Reset method, which ShoppingCart already defines.
6[Resettable]
Error LAMA0500: The aspect 'Resettable' cannot introduce member 'ShoppingCart.Reset()' into type 'ShoppingCart' because it is already defined in type 'ShoppingCart'. Use a different OverrideStrategy or skip the member.

7internal partial class ShoppingCart
8{
9    private readonly List<string> _items = new();
10
11    public void Add( string item ) => this._items.Add( item );
12
13    public void Reset() => this._items.Clear();
14}
15

Resolution

Decide what should happen when the member already exists, and specify the override strategy. For declarative advice, set the WhenExists property of the [Introduce] attribute. For programmatic advice, pass the whenExists parameter of the advice method.

  • OverrideStrategy.Override overrides the existing member. If it's defined in the target type, the template replaces its implementation and can call the original implementation with meta.Proceed(). If it's defined in a base type, it must be virtual or abstract, and the aspect introduces an override member.
  • OverrideStrategy.Ignore keeps the existing member and skips the introduction.
  • OverrideStrategy.New introduces a member with the new modifier. It's only possible when the existing member is defined in a base type.

Alternatively, rename the introduced member or the existing member to remove the conflict.

In the following example, the aspect uses OverrideStrategy.Override, so it adds its logic to the existing Reset method.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0500.Fixed;
5
6public class ResettableAttribute : TypeAspect
7{
8    [Introduce( WhenExists = OverrideStrategy.Override )]
9    public void Reset()
10    {
11        Console.WriteLine( "Resetting the object." );
12        meta.Proceed();
13    }
14}
15
Source Code
1using System.Collections.Generic;
2

3namespace Doc.LAMA0500.Fixed;
4
5// Fixed: the aspect overrides the existing Reset method.
6[Resettable]
7internal partial class ShoppingCart
8{
9    private readonly List<string> _items = new();
10
11    public void Add( string item ) => this._items.Add( item );
12
13    public void Reset() => this._items.Clear();
14}
15
Transformed Code
1using System;
2using System.Collections.Generic;
3
4namespace Doc.LAMA0500.Fixed;
5
6// Fixed: the aspect overrides the existing Reset method.
7[Resettable]
8internal partial class ShoppingCart
9{
10    private readonly List<string> _items = new();
11
12    public void Add(string item) => this._items.Add(item);
13
14    public void Reset()
15    {
16        Console.WriteLine("Resetting the object.");
17        this._items.Clear();
18    }
19}
20

See also