| Severity | Warning |
| Reported by | Metalama.Patterns.Immutability |
| Message | The type of the '<FieldOrProperty>' <DeclarationKind> must be deeply immutable. |
Cause
When you apply the ImmutableAttribute aspect with the ImmutabilityKind.Deep argument, you declare that no object reachable from an instance of the type can be modified. Every instance field and automatic property must therefore be of a deeply immutable type. Metalama reports LAMA5022 when a read-only field, or a get-only or init-only automatic property, has a type that isn't deeply immutable. The first placeholder of the message is the field or property, and the second is its kind: field or property.
Deeply immutable types include intrinsic types like int and string, enums, most structs of the System namespace, immutable collections whose type arguments are deeply immutable, and types marked with [Immutable(ImmutabilityKind.Deep)]. Mutable collections like List, interfaces, and types marked only with [Immutable] (shallow immutability) aren't deeply immutable.
Writable fields and properties with a setter aren't checked for deep immutability, because they already cause LAMA5020 or LAMA5021. The check doesn't run at design time, so the warning appears only when you build the project.
In the following example, the Items property of the deeply immutable Order class is a List<string>.
1using Metalama.Patterns.Immutability;
2using System.Collections.Generic;
3
4namespace Doc.LAMA5022.Error;
5
6[Immutable( ImmutabilityKind.Deep )]
7public class Order
8{
9 public string Customer { get; }
10
11 // Warning: List<T> is a mutable type, so the property isn't deeply immutable.
Warning LAMA5022: The type of the 'Order.Items' property must be deeply immutable.
12 public List<string> Items { get; }
13
14 public Order( string customer, IEnumerable<string> items )
15 {
16 this.Customer = customer;
17 this.Items = new List<string>( items );
18 }
19}
20
Resolution
Do one of the following:
- Change the type of the field or property to a deeply immutable type, for instance an immutable collection, as in the following example.
- If the type is yours and is deeply immutable, mark it with
[Immutable(ImmutabilityKind.Deep)]. For a type you don't own, use the ConfigureImmutability fabric method. - If the type only needs to be shallowly immutable, remove the ImmutabilityKind.Deep argument.
1using Metalama.Patterns.Immutability;
2using System.Collections.Generic;
3using System.Collections.Immutable;
4
5namespace Doc.LAMA5022.Fixed;
6
7[Immutable( ImmutabilityKind.Deep )]
8public class Order
9{
10 public string Customer { get; }
11
12 // Fixed: ImmutableArray<string> is deeply immutable.
13 public ImmutableArray<string> Items { get; }
14
15 public Order( string customer, IEnumerable<string> items )
16 {
17 this.Customer = customer;
18 this.Items = items.ToImmutableArray();
19 }
20}
21