为啥我收到警告说必须初始化一个不可为空的字段(当我确定我正在初始化它时)?

Posted

技术标签:

【中文标题】为啥我收到警告说必须初始化一个不可为空的字段(当我确定我正在初始化它时)?【英文标题】:Why am I getting warning that a non-nullable field must be initialised (When I'm sure I'm initialising it)?为什么我收到警告说必须初始化一个不可为空的字段(当我确定我正在初始化它时)? 【发布时间】:2022-01-04 14:29:09 【问题描述】:

我有:

public abstract class Craft

    public Craft()
    
        CurrentQuadrant = new Point(0, 0);
    

    private Point _currentQuadrant;
    public Point CurrentQuadrant
    
        get => _currentQuadrant;
        set
        
            _currentQuadrant = value;
        
    

(点是一个简单的 x-y 对)。

为什么会给我Non-nullable field '_currentQuadrant' must contain a non-null value when exiting the constructor 的警告?分配不是确保它是非空的吗?

【问题讨论】:

我认为链接的答案实际上对您没有帮助。问题是编译器不够聪明,无法看到您分配了CurrentQuadrant 属性,而这又总是分配_currentQuadrant 字段。要么直接从构造函数设置_currentQuadrant,要么使CurrentQuadrant 成为没有显式支持字段的自动属性,即public Point CurrentQuadrant get; set; _currentQuadrant = new Point(0, 0); @Wyck Nullable Reference Types 出现在 C# 8,2 个主要版本之前 我确定我是.. - 如果你已经达到了你确定自己比编译器能够给予你的功劳更聪明的地步,应用警告抑制 编译器警告我们应该在退出构造函数之前给_currentQuadrant赋值。看来我们确实是通过调用CurrentQuadrant 的属性设置器来实现的,尽管是间接的。是否可能会发生某种异常导致_currentQuadrant 没有值?这个问题需要一个副本中没有提供的答案。例如:就像 canton7 的第一条评论,暗示实际原因是编译器还不够聪明,无法得出在这种情况下发生了赋值的结论。 【参考方案1】:

声誉太低,无法评论,所以我会在这里发布。

如果您使用的是 .NET 5+,则可以使用 [MemberNotNull] 属性(更多信息 here)。

只需将[MemberNotNull(nameof(_currentQuadrant)] 放在您的构造函数上,警告就会消失。

或者您可以将值分配给_currentQuadrant 而不是CurrentQuadrant

【讨论】:

以上是关于为啥我收到警告说必须初始化一个不可为空的字段(当我确定我正在初始化它时)?的主要内容,如果未能解决你的问题,请参考以下文章

必须初始化不可为空的实例字段“_selectedSize”

必须初始化不可为空的实例字段

必须初始化不可为空的实例字段“_localizedStrings”

Flutter-不可为空的实例字段'questionAnswer','questionText'必须初始化

Schema graphql 错误给出“不能为不可为空的字段 Organisation.id 返回 null”为啥?

颤振错误->必须初始化不可为空的“项目”