var x = something.Relation.Where(x => ...); // no warning here
我想知道如何告诉编译器某个属性永远不会为空,尽管编译器没有看到任何初始化代码。当前编译器发出警告:
不可为空的属性未初始化。考虑将属性声明为可为空
我最常见的情况是由 ORM 框架初始化的实体。它们要么在创建实体实例时由 ORM 自动实例化,要么后处理器分析程序集并注入初始化代码。因此,当一个新实例由一个简单new MyEntity()
的引用类型的某些属性创建时已经是非空的,尽管编译器没有看到这一点。
案例 1:与其他实体的关系
该[Association]
属性由 ORM 以特定方式处理,确保EntitySet<T>
类型的属性自动初始化为这些集合的实际实例。
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; }
}
案例2:嵌套实例(组合)
属性类型的父类型触发 ORM 的特定处理,确保实例是自动创建的:
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
}
当前可用的注释:
一种可能性是用属性注释整个[NotNull]
属性。但是,在这种情况下,警告不会立即消失,并且有必要使用可为空的引用类型来删除属性:
[Field]
[Association]
[NotNull]
public EntitySet<OtherEntity>? Relation { get; set; }
这是一个部分可接受的解决方案,因为声明站点警告已被删除,并且在取消引用该Relation
属性时不会在使用站点引起警告:
var x = something.Relation.Where(x => ...); // no warning here
但是,?
同时使用 a[NotNull]
似乎违反直觉。
另一种选择是应用于[NotNull]
getter 的返回。但是,除非使用可为空的引用类型,否则警告不会消失:
[Field]
[Association]
public EntitySet<OtherEntity>? Relation { [return: NotNull] get; set; }
这减轻了声明站点警告,但使用站点警告仍然存在:
var x = something.Relation.Where(x => ...); // warning here
问题是,是否有一种方法可以在不使用可为空引用类型的情况下对此类属性进行空注释,或者这些场景是否不受现有属性集的支持,并且应该在 dotnet github 存储库中提出票证?