| Severity | Warning |
| Reported by | Metalama.Patterns.Contracts |
| Message | The meaning of the [<OldName>] attribute on '<Declaration>' is ambiguous because the inequality strictness is not specified. It is now interpreted as <Strictness>, which is non-standard, and this behavior might be changed in the future. Use either [<NewName1>] or [<NewName2>], or specify the DefaultInequalityStrictness property in ContractOptions using the ConfigureContracts fabric extension method. |
Cause
The [Positive], [Negative], [GreaterThan], and [LessThan] contracts exist for backward compatibility. Contrary to the usual meaning of their names, they enforce a non-strict inequality: for instance, [Positive] accepts zero.
Metalama reports LAMA5007 on each use of these contracts, unless the DefaultInequalityStrictness option specifies how to interpret them. The message gives the current interpretation and names the two unambiguous contracts that can replace the attribute. The contract still works: Metalama generates the non-strict check.
In the following example, [Positive] is applied to a Price property, so a price of zero is accepted, which may not be the intent.
Source Code
1using Metalama.Patterns.Contracts;
2
3namespace Doc.LAMA5007.Error;
4
5public class Product
6{
7 // Warning: [Positive] doesn't say whether zero is allowed.
Warning LAMA5007: The meaning of the [PositiveAttribute] attribute on 'Product.Price' is ambiguous because the inequality strictness is not specified. It is now interpreted as NonStrict, which is non-standard, and this behavior might be changed in the future. Use either [NonNegativeAttribute] or [StrictlyPositiveAttribute], or specify the DefaultInequalityStrictness property in ContractOptions using the ConfigureContracts fabric extension method.
8 [Positive]
9 public decimal Price { get; set; }
10}
11
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5007.Error;
5
6public class Product
7{
8 private decimal _price;
9
10 // Warning: [Positive] doesn't say whether zero is allowed.
11 [Positive]
12 public decimal Price
13 {
14 get
15 {
16 return _price;
17 }
18
19 set
20 {
21 if (value < 0M)
22 {
23 throw new ArgumentOutOfRangeException("value", value, "The 'Price' property must be greater than or equal to 0.");
24 }
25
26 _price = value;
27 }
28 }
29}
30
Resolution
Do one of the following:
- Replace the attribute with the unambiguous contract that matches your intent. For
[Positive], use [StrictlyPositive] to reject zero, or [NonNegative] to keep the current behavior. The following example uses[StrictlyPositive]. - Keep the attributes and set the DefaultInequalityStrictness option for the whole project or namespace using the ConfigureContracts extension method in a fabric. This option decides how all ambiguous contracts in its scope are interpreted.
Source Code
1using Metalama.Patterns.Contracts;
2
3namespace Doc.LAMA5007.Fixed;
4
5public class Product
6{
7 // Fixed: [StrictlyPositive] states explicitly that zero isn't allowed.
8 [StrictlyPositive]
9 public decimal Price { get; set; }
10}
11
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5007.Fixed;
5
6public class Product
7{
8 private decimal _price;
9
10 // Fixed: [StrictlyPositive] states explicitly that zero isn't allowed.
11 [StrictlyPositive]
12 public decimal Price
13 {
14 get
15 {
16 return _price;
17 }
18
19 set
20 {
21 if (value <= 0M)
22 {
23 throw new ArgumentOutOfRangeException("value", value, "The 'Price' property must be strictly greater than 0.");
24 }
25
26 _price = value;
27 }
28 }
29}
30