Open sandboxFocusImprove this doc

LAMA5002: A non-nullable contract is applied to a nullable type

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 null isn'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 null is 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 false from 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

See also