var x = something.Relation.Where(x => ...); // no warning here
I am wondering how to tell the compiler that a certain property will never be null, despite the compiler does not see any initialization code. Currently the compiler issues a warning:
Non-nullable property is uninitialized. Consider declaring the property as nullable
My most frequent cases are entities initialized by an ORM framework. Either, they are auto-instantiated by the ORM when the entity instance is created, or a post-processor analyzes the assembly and injects initialization code. Hence, when a new instance is created by a simple new MyEntity()
certain properties of reference types are already non-null, despite the compiler doesn't see that.
Case 1: Relationships to other entities
The [Association]
attribute is handled in a specific way by the ORM, ensuring properties of EntitySet<T>
types are auto-initialized to actual instances of these collections.
public class MyEntity : Entity
{
// this reference will never be null, warning here
[Field]
[Association]
public EntitySet<OtherEntity> Relation { get; set; } // * the setter might be omitted
// this reference will never be null, warning here
[Field]
[Association]
public ParentEntity Parent { get; set; }
// here it is clearly annotated that this reference may be null, no warning, obviously
[Field]
[Association]
public OtherEntity? Relationship { get; set; }
}
Case 2: Nested instance (composition)
The parent type of the property's type triggers a specific handling by the ORM, ensuring the instance is auto-created:
public class MyEntity : Entity
{
// this is, in fact, an aggregation and is always initialized by the ORM, warning here
[Field]
public NestedPart SubPart { get; set; } // * the setter might be omitted
}
Currently available annotations:
One possibility is to annotate the whole property with a [NotNull]
attribute. However, in that case the warning won't go away immediatelly, and it's necessary to delcare the property with a nullable reference type:
[Field]
[Association]
[NotNull]
public EntitySet<OtherEntity>? Relation { get; set; }
This is a partially acceptable solution, as both declaration-site warning is removed and when dereferencing the Relation
property it won't cause a warning at use-site:
var x = something.Relation.Where(x => ...); // no warning here
However, using the ?
at the same time a [NotNull]
seems counter-intuitive.
Another option is to apply [NotNull]
to the return of the getter. However, again the warning won't go away unless a nullable reference type is used:
[Field]
[Association]
public EntitySet<OtherEntity>? Relation { [return: NotNull] get; set; }
This mitigates the declaration-site warning, but the use-site warning remains:
var x = something.Relation.Where(x => ...); // warning here
The question is, whether there is a way to null-annotate such properties without using nullable reference types, or whether these scenarios are unsupported by the existing set of attributes and a ticket should be raised in the dotnet github repo?