| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The aspect '<AspectType>' cannot introduce member '<Member>' into type '<TargetType>' with OverrideStrategy.New because the member is already declared in the type. |
Cause
When an aspect introduces a method, property, field, event, or indexer, the OverrideStrategy of the advice decides what happens if the member already exists. You set it with the WhenExists property of the [Introduce] attribute, or with the whenExists parameter of the programmatic advice methods.
With OverrideStrategy.New, Metalama introduces the member with the new modifier, which hides a member with the same signature inherited from a base type. This only works when the existing member is declared in a base type. C# doesn't allow two members with the same signature in the same type, so Metalama reports LAMA0509 when the target type itself declares the member.
In the following example, the Describe aspect introduces a Describe method with OverrideStrategy.New, but the Product class already declares Describe.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0509.Error;
5
6public class DescribeAttribute : TypeAspect
7{
8 // The aspect introduces the method with OverrideStrategy.New.
9 [Introduce( WhenExists = OverrideStrategy.New )]
10 public string Describe()
11 {
12 Console.WriteLine( "Describing the object." );
13
14 return meta.Proceed()!;
15 }
16}
17
1namespace Doc.LAMA0509.Error;
2
3// Error: Product already declares Describe(), so OverrideStrategy.New can't hide it.
4[Describe]
Error LAMA0509: The aspect 'Describe' cannot introduce member 'Product.Describe()' into type 'Product' with OverrideStrategy.New because the member is already declared in the type.
5internal partial class Product
6{
7 public string Describe() => "Product";
8}
9
Resolution
Choose the strategy that matches your intent for types that already declare the member:
- Use OverrideStrategy.Override to override the existing member with the template. Call meta.Proceed() in the template to invoke the original implementation.
- Use OverrideStrategy.Ignore to keep the existing member unchanged.
- Remove or rename the member in the target type if it shouldn't be there.
Keep OverrideStrategy.New for members that are inherited from a base type.
In the following example, the aspect uses OverrideStrategy.Override, so it wraps the existing Describe method.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0509.Fixed;
5
6public class DescribeAttribute : TypeAspect
7{
8 // The aspect overrides the method when the type already declares it.
9 [Introduce( WhenExists = OverrideStrategy.Override )]
10 public string Describe()
11 {
12 Console.WriteLine( "Describing the object." );
13
14 return meta.Proceed()!;
15 }
16}
17
1namespace Doc.LAMA0509.Fixed;
2
3// Fixed: the aspect uses OverrideStrategy.Override, so it overrides the existing Describe() method.
4[Describe]
5internal partial class Product
6{
7 public string Describe() => "Product";
8}
9
1using System;
2
3namespace Doc.LAMA0509.Fixed;
4
5// Fixed: the aspect uses OverrideStrategy.Override, so it overrides the existing Describe() method.
6[Describe]
7internal partial class Product
8{
9 public string Describe()
10 {
11 Console.WriteLine("Describing the object.");
12 return "Product";
13 }
14}
15