| Severity | Warning |
| Reported by | Metalama.Patterns.Contracts |
| Message | The [<AspectType>] contract has been applied to '<Declaration>', but its type is nullable. |
Cause
The NotNullAttribute and RequiredAttribute contracts throw an exception when the target is assigned null. Metalama reports LAMA5002 when one of these contracts is applied to a field, property, or parameter whose type is nullable, for instance a string? or an int?. The declaration and the contract contradict each other: the type says that null is a valid value, but the contract rejects it.
The warning isn't reported for declarations whose type is a generic type parameter. The contract still applies and generates its null check.
In the following example, the Email property is declared as string?, but it has a [NotNull] contract.
Source Code
1using Metalama.Patterns.Contracts;
2
3namespace Doc.LAMA5002.Error;
4
5public class Customer
6{
7 // Warning: the [NotNull] contract contradicts the nullable type.
8 [NotNull]
Warning LAMA5002: The [NotNull] contract has been applied to 'Customer.Email', but its type is nullable.
9 public string? Email { get; set; }
10}
11
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5002.Error;
5
6public class Customer
7{
8 private string? _email;
9
10 // Warning: the [NotNull] contract contradicts the nullable type.
11 [NotNull]
12 public string? Email
13 {
14 get
15 {
16 return _email;
17 }
18
19 set
20 {
21 if (value == null!)
22 {
23 throw new ArgumentNullException("value", "The 'Email' property must not be null.");
24 }
25
26 _email = value;
27 }
28 }
29}
30
Resolution
Do one of the following:
- If
nullisn't a valid value, make the type non-nullable, as in the following example. The C# compiler then also warns callers that pass a possibly null value. - If
nullis a valid value, remove the contract. - If you need nullable types with non-nullable contracts, disable the warning by setting the WarnOnNotNullableOnNullable property of ContractOptions to
falsefrom a fabric, as described in Configuring contracts.
Source Code
1using Metalama.Patterns.Contracts;
2
3namespace Doc.LAMA5002.Fixed;
4
5public class Customer
6{
7 // Fixed: the type is non-nullable, consistently with the [NotNull] contract.
8 [NotNull]
9 public string Email { get; set; } = "";
10}
11
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5002.Fixed;
5
6public class Customer
7{
8 private string _email = "";
9
10 // Fixed: the type is non-nullable, consistently with the [NotNull] contract.
11 [NotNull]
12 public string Email
13 {
14 get
15 {
16 return _email;
17 }
18
19 set
20 {
21 if (value == null!)
22 {
23 throw new ArgumentNullException("value", "The 'Email' property must not be null.");
24 }
25
26 _email = value;
27 }
28 }
29}
30