C#抽象类泛型T:notnull约束下可空引用类型告警如何解决
问题解决方案
泛型约束改为struct是否有效
- 该方案确实可以消除告警:值类型(struct)自带隐式默认构造函数,会生成对应类型的默认值,天然满足构造结束后属性非空的要求,所以编译器告警会消失。
- 存在适用限制:
struct约束会禁止使用引用类型作为Id(比如业务中常用的字符串类型主键),如果你的项目存在需要用引用类型作为Id的实体,就不能采用这个方案。
通用告警消除方案
方案1:使用default!抑制空警告(最灵活)
直接给Id属性赋值default!,相当于你向编译器承诺业务逻辑中一定会在使用Id前完成赋值,不会出现空值情况,修改后代码如下:
public abstract class Entity<T> : Entity, IEntity<T> where T : notnull { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public virtual T Id { get; protected set; } = default!; }
适用场景:需要支持字符串等引用类型作为Id,且可以保证通过构造函数、ORM框架赋值等方式在使用前完成Id初始化。
方案2:添加带参构造函数强制初始化Id(最安全)
给抽象类添加受保护的带参构造函数,强制所有子类实例化时必须传入Id值,从语法层面保证Id不会为空,若需要兼容ORM框架的无参构造要求,可以额外加无参构造配合default!使用,代码如下:
public abstract class Entity<T> : Entity, IEntity<T> where T : notnull { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public virtual T Id { get; protected set; } // 强制子类传Id的构造函数 protected Entity(T id) { Id = id; } // 兼容EF Core等ORM框架的无参构造需求 protected Entity() { Id = default!; } }
适用场景:希望从编码层面避免忘记初始化Id的问题,同时兼容引用类型Id的需求。
内容的提问来源于stack exchange,提问作者Deivydas Voroneckis
相关产品推荐
相关产品推荐

