Steeltoe
Steeltoe copied to clipboard
Adopt nullable reference types
This issue tracks annotating the codebase for nullable reference types.
General guidance:
- Compile/test against .NET 7 or higher (only the core libraries are annotated in .NET 6, and several are wrong)
- Always declare collection properties using interfaces (
IList<JsonService>instead ofList<JsonService>) - IOptions pattern
- Declare collection properties as non-nullable get-only and initialize with an empty collection
- They cannot be set to null from JSON, see https://github.com/dotnet/extensions/issues/1341
- The configuration binder supports adding to an existing collection instance
- Always declare scalar reference-type properties as nullable (and null-check before use)
- There's no guarantee that
IConfigureOptions<>has executed before usage - Developers may register their own
IConfigureOptions<>that sets the value tonull - The property may be explicitly set to
nullfrom appsettings.json
- There's no guarantee that
- Declare collection properties as non-nullable get-only and initialize with an empty collection
- Types used in JSON serialization
- Declare collection properties with both a getter and a setter
- Although
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]was added in .NET 8, it cannot be combined with custom converters (so adding one later would require a breaking change)
- Although
- Deserialization
- Declare collection properties as nullable if
nullhas a semantic meaning that differs from an empty collection, or when it's unknown whether the source may produce nulls. - Initialize with an empty collection if not declared as nullable
- Declare collection properties as nullable if
- Serialization
- It's safest to declare all reference-type properties as nullable, because it affects the JSON output
- If a collection is conditionally populated (ie
nullhas meaning), make the property nullable - If a collection is always populated, declare it as non-nullable and initialize with an empty collection
- If a collection is conditionally populated (ie
- It's safest to declare all reference-type properties as nullable, because it affects the JSON output
- Declare collection properties with both a getter and a setter
- Other types
- Declare all required properties as non-nullable
- Replace property setters with a constructor that takes all required properties, and add guard checks
- Declare all required properties as non-nullable
- Try to minimize the use of the
!operator to suppress nullability warnings; consider adding a comment when unobvious