| Severity | Warning |
| Reported by | Metalama.Patterns.Contracts |
| Message | The [<AspectType>] contract is redundant because a fabric automatically adds the [NotNull] contract to this declaration. |
Cause
The VerifyNotNullableDeclarations fabric method adds the NotNullAttribute contract to the public fields, properties, and parameters of a non-nullable reference type. Metalama reports LAMA5003 when one of these declarations also has an explicit contract that the fabric makes redundant:
- a
[NotNull]contract; - a RequiredAttribute contract, unless the type is
string. On a string,[Required]also rejects empty and white-space values, so it isn't redundant.
The explicit contract still works, so the generated code doesn't change. The warning only tells you that the attribute is unnecessary.
In the following example, the project fabric calls VerifyNotNullableDeclarations, and the name parameter also has an explicit [NotNull] contract.
1using Metalama.Framework.Fabrics;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5003.Error;
5
6internal class Fabric : ProjectFabric
7{
8 public override void AmendProject( IProjectAmender amender )
9 {
10 // Adds [NotNull] to all public non-nullable reference-typed parameters, fields, and properties.
11 amender.VerifyNotNullableDeclarations();
12 }
13}
14
Source Code
1using Metalama.Patterns.Contracts;
2
3namespace Doc.LAMA5003.Error;
4
5public class GreetingService
6{
7 // Warning: the fabric already adds [NotNull] to this parameter.
Warning LAMA5003: The [NotNullAttribute] contract is redundant because a fabric automatically adds the [NotNull] contract to this declaration.
8 public string Greet( [NotNull] string name ) => $"Hello, {name}.";
9}
10
Transformed Code
1using System;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5003.Error;
5
6public class GreetingService
7{
8 // Warning: the fabric already adds [NotNull] to this parameter.
9 public string Greet([NotNull] string name)
10 {
11 if (name == null!)
12 {
13 throw new ArgumentNullException("name", "The 'name' parameter must not be null.");
14 }
15
16 return $"Hello, {name}.";
17 }
18}
19
Resolution
Remove the explicit contract. The fabric adds the same null check, as the following example shows.
1using Metalama.Framework.Fabrics;
2using Metalama.Patterns.Contracts;
3
4namespace Doc.LAMA5003.Fixed;
5
6internal class Fabric : ProjectFabric
7{
8 public override void AmendProject( IProjectAmender amender )
9 {
10 // Adds [NotNull] to all public non-nullable reference-typed parameters, fields, and properties.
11 amender.VerifyNotNullableDeclarations();
12 }
13}
14
Source Code
1namespace Doc.LAMA5003.Fixed;
2
3public class GreetingService
4{
5 // Fixed: no explicit [NotNull] contract; the fabric adds it.
6 public string Greet( string name ) => $"Hello, {name}.";
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA5003.Fixed;
4
5public class GreetingService
6{
7 // Fixed: no explicit [NotNull] contract; the fabric adds it.
8 public string Greet(string name)
9 {
10 if (name == null!)
11 {
12 throw new ArgumentNullException("name", "The 'name' parameter must not be null.");
13 }
14
15 return $"Hello, {name}.";
16 }
17}
18