| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The aspect '<AspectType>' cannot introduce the indexer '<Member>' into the type '<TargetType>' because the indexer has no parameter. An indexer must have at least one parameter. |
Cause
In C#, an indexer must have at least one parameter. When an aspect introduces an indexer with the IntroduceIndexer method, the parameters of the indexer come from the indices argument and from the buildIndexer delegate.
Metalama reports LAMA0526 when the introduced indexer has no parameter after the buildIndexer delegate has run, for instance because the aspect passes an empty list of indices. The error is reported on the target type, and <Member> shows the indexer with empty brackets, for example ProductCatalog.this[].
In the following example, the Indexer aspect passes an empty list of indices.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0526.Error;
6
7public class IndexerAttribute : TypeAspect
8{
9 public override void BuildAspect( IAspectBuilder<INamedType> builder )
10 {
11 builder.IntroduceIndexer(
12 // Error: the list of indexer parameters is empty.
13 Array.Empty<(Type, string)>(),
14 nameof(this.GetItem),
15 nameof(this.SetItem),
16 buildIndexer: indexer => { indexer.Accessibility = Accessibility.Public; } );
17 }
18
19 [Template]
20 public dynamic? GetItem()
21 {
22 Console.WriteLine( "Getting an item." );
23
24 return meta.Proceed();
25 }
26
27 [Template]
28 public void SetItem( dynamic? value )
29 {
30 Console.WriteLine( "Setting an item." );
31 meta.Proceed();
32 }
33}
34
1namespace Doc.LAMA0526.Error;
2
3// Error: the [Indexer] aspect introduces an indexer without any parameter.
4[Indexer]
Error LAMA0526: The aspect 'Indexer' cannot introduce the indexer 'ProductCatalog.this[]' into the type 'ProductCatalog' because the indexer has no parameter. An indexer must have at least one parameter.
5internal partial class ProductCatalog { }
6
Resolution
Give the indexer at least one parameter:
- Pass at least one
(type, name)pair in theindicesargument ofIntroduceIndexer. - If the aspect computes the indices from the target type, check that the list isn't empty before calling
IntroduceIndexer, and skip the introduction or report your own diagnostic when it's empty.
In the following example, the indexer has an int parameter.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0526.Fixed;
6
7public class IndexerAttribute : TypeAspect
8{
9 public override void BuildAspect( IAspectBuilder<INamedType> builder )
10 {
11 builder.IntroduceIndexer(
12 // Fixed: the indexer has one parameter.
13 new[] { ( typeof(int), "index" ) },
14 nameof(this.GetItem),
15 nameof(this.SetItem),
16 buildIndexer: indexer => { indexer.Accessibility = Accessibility.Public; } );
17 }
18
19 [Template]
20 public dynamic? GetItem()
21 {
22 Console.WriteLine( "Getting an item." );
23
24 return meta.Proceed();
25 }
26
27 [Template]
28 public void SetItem( dynamic? value )
29 {
30 Console.WriteLine( "Setting an item." );
31 meta.Proceed();
32 }
33}
34
Source Code
1namespace Doc.LAMA0526.Fixed;
2
3// Fixed: the [Indexer] aspect introduces an indexer with an 'int' parameter.
4[Indexer]
5internal partial class ProductCatalog { }
6
Transformed Code
1using System;
2
3namespace Doc.LAMA0526.Fixed;
4
5// Fixed: the [Indexer] aspect introduces an indexer with an 'int' parameter.
6[Indexer]
7internal partial class ProductCatalog
8{
9 public object? this[int index]
10 {
11 get
12 {
13 Console.WriteLine("Getting an item.");
14 return default(object?);
15 }
16 set
17 {
18 Console.WriteLine("Setting an item.");
19 }
20 }
21}
22