为什么Resharper告诉我可能存在NullReferenceException?

时间:2020-01-13 15:40:02

标签: c# resharper rider

我将Rider中的“值分析”模式切换为“悲观”,以突出显示每个“ Possible NullReferenceException”,并且在下面的示例中,我在“ Languages [0]”部分显示了警告,并且我不明白为什么,因为我初始化了我的声明后立即收藏。

那么它就不能为空。

我刚刚在一个空项目中进行了测试,并且有相同的警告。

using System.Collections.Generic;

namespace ClassLibrary1
{
    public class Class1
    {
        public static string Current => Languages[0];

        public static readonly List<string> Languages = new List<string>
        {
            "en"
        };
    }
}

这是ReSharper犯的错误还是我错过了什么?

谢谢。

2 个答案:

答案 0 :(得分:1)

我认为静态属性是按外观顺序进行评估的。尝试翻转它们,以便首先具有“语言”,然后具有“当前”。

答案 1 :(得分:1)

尝试一下:

public static class Program
{
    public static readonly string Foo = Current;

    public static string Current => Languages[0];

    public static readonly List<string> Languages = new List<string>
    {
        "en"
    };

    public static void Main()
    {
        Console.WriteLine(Foo);
    }
}

SharpLab

静态成员按照声明的顺序进行初始化。 Foo在分配Languages之前被初始化,因此您会看到NullReferenceException

我猜想Resharper在这里非常悲观,并且只考虑孤立地Current,无论在初始化Languages之前是否实际上还有另一个静态成员可以访问它。


您也可能会遇到类似这样的问题,其中Languages的构造会导致某些东西可以访问Program.Current

public static class Program
{
    public static string Current => Languages[0].Value;
    public static readonly List<Language> Languages = new List<Language>() { new Language() };

    public static void Main()
    {
        Console.WriteLine(Current);
    }
}

public class Language
{
    public string Value { get; } = Program.Current;
}

(这是一个愚蠢的示例,但它表明Resharper可能很难证明Program.Current的类型初始化程序未运行之前,没有人可以访问Program,这超出了您的预期)。