Open sandboxFocusImprove this doc

LAMA0531: A type with the same name already exists

Severity Error
Reported by Metalama.Framework
Message The aspect '<AspectType>' cannot introduce the type '<Type>' into '<TargetNamespaceOrType>' because '<TargetNamespaceOrType>' already contains or inherits a type with the same name and the same number of type parameters. Use a different name, or specify another OverrideStrategy.

Cause

The IntroduceClass method introduces a new class into a namespace or, as a nested type, into a type. Before introducing it, Metalama checks whether the target already has a type with the same name and the same number of type parameters. For a target type, this includes the nested types inherited from its base types and the types introduced by other aspects.

The whenExists argument decides what happens in this case. Its default value behaves like OverrideStrategy.Fail: Metalama reports LAMA0531. In the message, <Type> is the type that the aspect tries to introduce, and <TargetNamespaceOrType> is the target namespace or type.

In the following example, the Memento aspect introduces a nested class named Snapshot, but the target class already has a nested class with this name.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0531.Error;
5
6public class MementoAttribute : TypeAspect
7{
8    public override void BuildAspect( IAspectBuilder<INamedType> builder )
9    {
10        // Error: the target type already has a nested type named Snapshot.
11        builder.IntroduceClass( "Snapshot", buildType: type => type.Accessibility = Accessibility.Public );
12    }
13}
14
1namespace Doc.LAMA0531.Error;
2
3[Memento]
Error LAMA0531: The aspect 'Memento' cannot introduce the type 'Document.Snapshot' into 'Document' because 'Document' already contains or inherits a type with the same name and the same number of type parameters. Use a different name, or specify another OverrideStrategy.

4internal partial class Document
5{
6    public string? Text { get; set; }
7
8    // Error: the [Memento] aspect tries to introduce another nested type named Snapshot.
9    public class Snapshot
10    {
11        public int Version { get; set; }
12    }
13}
14

Resolution

Do one of the following:

  • Give the introduced type a name that doesn't conflict with existing types. If you're the author of the aspect, choose a specific name, as in the following example. Otherwise, rename the existing type.
  • Pass OverrideStrategy.Ignore as the whenExists argument to keep the existing type and skip the introduction. The advice result then refers to the existing type.
  • When the conflicting type is a nested type inherited from a base type, pass OverrideStrategy.New to introduce a type that hides the inherited one with the new modifier.

1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3
4namespace Doc.LAMA0531.Fixed;
5
6public class MementoAttribute : TypeAspect
7{
8    public override void BuildAspect( IAspectBuilder<INamedType> builder )
9    {
10        // Fixed: the introduced type has a name that doesn't conflict with the existing nested type.
11        builder.IntroduceClass( "Memento", buildType: type => type.Accessibility = Accessibility.Public );
12    }
13}
14
Source Code
1namespace Doc.LAMA0531.Fixed;
2
3[Memento]
4internal partial class Document
5{
6    public string? Text { get; set; }
7
8    // Fixed: the [Memento] aspect introduces a nested type with another name.
9    public class Snapshot
10    {
11        public int Version { get; set; }
12    }
13}
14
Transformed Code
1namespace Doc.LAMA0531.Fixed;
2
3[Memento]
4internal partial class Document
5{
6    public string? Text { get; set; }
7
8    // Fixed: the [Memento] aspect introduces a nested type with another name.
9    public class Snapshot
10    {
11        public int Version { get; set; }
12    }
13
14    public class Memento
15    {
16    }
17}
18

See also