c# - 为什么这段代码会给出 "Possible null reference return"编译器警告?

标签 c# nullable-reference-types

考虑以下代码:

using System;

#nullable enable

namespace Demo
{
    public sealed class TestClass
    {
        public string Test()
        {
            bool isNull = _test == null;

            if (isNull)
                return "";
            else
                return _test; // !!!
        }

        readonly string _test = "";
    }
}

当我构建它时,标有 !!! 的行给出了编译器警告: warning CS8603: Possible null reference return.

我觉得这有点令人困惑,因为 _test 是只读的并且初始化为非空值。

如果我将代码更改为以下内容,警告就会消失:
        public string Test()
        {
            // bool isNull = _test == null;

            if (_test == null)
                return "";
            else
                return _test;
        }

谁能解释这种行为?

最佳答案

可空流分析跟踪变量的空状态,但不跟踪其他状态,例如 bool 变量的值(如上面的 isNull),也不跟踪单独变量的状态(例如 isNull_test)。

一个实际的静态分析引擎可能会做这些事情,但在某种程度上也会是“启发式”或“任意”的:你不一定能说出它遵循的规则,这些规则甚至可能会随着时间的推移而改变。

这不是我们可以直接在 C# 编译器中做的事情。可空警告的规则非常复杂(正如 Jon 的分析所示!),但它们是规则,可以推理。

当我们推出该功能时,感觉我们大部分时间都达到了正确的平衡,但有一些地方确实很尴尬,我们将在 C# 9.0 中重新审视这些地方。

关于c# - 为什么这段代码会给出 "Possible null reference return"编译器警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59306751/

相关文章:

c# - 即使没有空值,为什么会发出有关可为空类型的警告?

C# 不可空字段 : Lateinit?

c# - 如何为整个项目启用 C# 8.0 的可空引用类型功能

c# - 获取新 AppDomain 中加载的程序集的类型

c# - 我如何遍历 List<T> 并获取每个项目?

c# - 如何适本地设计数据访问层?

c# - 取消异步套接字操作

c# 8 nullable + 字典<>

c# - C# 8 是否注释可为 null 的属性和参数?

c# - 当 DropDownStyle 为 DropDown 时,ComboBox Cue Banner 不是斜体