Open sandboxFocusImprove this doc

LAMA5006: The range contract is redundant for the type of the declaration

Severity Warning
Reported by Metalama.Patterns.Contracts
Message The [<AspectType>] contract is redundant on '<Declaration>' because the value range <Range> is always satisfied by the type <TargetBasicType>.

Cause

Range contracts, such as [Range], [NonNegative], or [LessThanOrEqual], check at run time that a value lies within a range. Metalama reports LAMA5006 when every bound of the range is at or beyond the limits of the numeric type of the field, property, or parameter, so that no value of the type can violate the contract. For instance, a uint can't be negative, and a byte is always within [0, 255].

Because the check could never fail, Metalama doesn't generate it and ignores the contract. The message shows the range, where โˆž means that the range has no bound on that side, and the name of the type.

In the following example, the [NonNegative] contract is applied to a uint property.

Source Code
1using Metalama.Patterns.Contracts;
2

3namespace Doc.LAMA5006.Error;
4
5public class OrderLine
6{
7    // Warning: a uint value can never be negative.
8    [NonNegative]
    Warning LAMA5006: The [NonNegative] contract is redundant on 'OrderLine.Quantity' because the value range [0, โˆž] is always satisfied by the type UInt32.

9    public uint Quantity { get; set; }
10
11    [NonNegative]


12    public decimal UnitPrice { get; set; }
13}
14
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5006.Error;
5
6public class OrderLine
7{
8    // Warning: a uint value can never be negative.
9    [NonNegative]
10    public uint Quantity { get; set; }
11
12    private decimal _unitPrice;
13
14    [NonNegative]
15    public decimal UnitPrice
16    {
17        get
18        {
19            return _unitPrice;
20        }
21
22        set
23        {
24            if (value < 0M)
25            {
26                throw new ArgumentOutOfRangeException("value", value, "The 'UnitPrice' property must be greater than or equal to 0.");
27            }
28
29            _unitPrice = value;
30        }
31    }
32}
33

Resolution

Depending on your intent, do one of the following:

  • Remove the contract, because the type already enforces the range. The following example shows this fix.
  • If you meant a stricter condition, use a contract that expresses it, for instance [StrictlyPositive] to exclude zero, or narrow the bounds of the [Range] contract.

Source Code
1using Metalama.Patterns.Contracts;
2

3namespace Doc.LAMA5006.Fixed;
4
5public class OrderLine
6{
7    // Fixed: the uint type already excludes negative values, so the contract is removed.
8    public uint Quantity { get; set; }
9
10    [NonNegative]


11    public decimal UnitPrice { get; set; }
12}
13
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5006.Fixed;
5
6public class OrderLine
7{
8    // Fixed: the uint type already excludes negative values, so the contract is removed.
9    public uint Quantity { get; set; }
10
11    private decimal _unitPrice;
12
13    [NonNegative]
14    public decimal UnitPrice
15    {
16        get
17        {
18            return _unitPrice;
19        }
20
21        set
22        {
23            if (value < 0M)
24            {
25                throw new ArgumentOutOfRangeException("value", value, "The 'UnitPrice' property must be greater than or equal to 0.");
26            }
27
28            _unitPrice = value;
29        }
30    }
31}
32

See also