Почему Resharper говорит мне, что возможно исключение NullReferenceException? - PullRequest
0 голосов
/ 13 января 2020

Я переключил режим анализа значений в Rider на Pessimisti c, чтобы выделить каждое «возможное исключение 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 ]

1 голос
/ 13 января 2020

Попробуйте это:

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

Stati c члены инициализируются в порядке их объявления. Foo инициализируется до присвоения Languages, и поэтому вы видите NullReferenceException.

Я предполагаю, что Решарпер очень пессимистичен c здесь и рассматривает только Current в изоляции, независимо от есть ли на самом деле другой элемент stati c, который может получить к нему доступ до инициализации 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, чем вы могли бы ожидать).

1 голос
/ 13 января 2020

Я думаю, что свойства c оцениваются в порядке появления. Попробуйте перевернуть их, чтобы сначала были «Языки», а затем «Текущий».

...