Отладчик C # сообщает о неправильном имени поля как ноль, когда выбрасывается исключение NullReferenceException - PullRequest
0 голосов
/ 23 апреля 2019

У меня очень странный случай, когда в моем классе есть нулевой параметр, к которому я пытаюсь получить доступ (и, следовательно, вызываю исключение NullReferenceException), однако вместо этого отладчик сообщает, что поле из другого совершенно не связанного класса является пустым. Я пытался воспроизвести это, однако я не могу. Кто-нибудь может объяснить, что происходит?

Я создал новый небольшой тестовый проект с теми же классами.

namespace WpfApp6
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Test_Click(object sender, RoutedEventArgs e)
        {
            var container = new SegmentedBinaryData();
            var temp = container.StringData[0x123,10];
        }
    }

    public class SegmentedBinaryData
    {
        public StringData StringData;
    }

    public class StringData
    {
        public string this[int address, int maxLength]
        {
            get => "lol";
            set { }
        }
    }
}

Если вы запустите этот тестовый проект и нажмете кнопку «Тест», вы получите следующее исключение:

System.NullReferenceException: 'Object reference not set to an
instance of an object.' container.StringData was null.

Это имеет смысл. В моем реальном проекте я получаю следующее исключение:

System.NullReferenceException: 'Object reference not set to an
instance of an object.' container.<SmoothXEnabled>k__BackingField was null.

SmoothXEnabled - это логическое свойство другого класса, которое даже не находится в том же пространстве имен, не говоря уже о том, что на него даже не ссылается эта сборка.

Должно быть сказано, что «StringData» была нулевой, но это не так. Почему отладчик VS2019 запутывается здесь? Я попытался отладки с VS2017, и я получаю ту же ошибку

Я отлаживал программу в dnspy, и она просто говорит: «Ссылка на объект не установлена ​​для экземпляра объекта». вместо этого ошибка, которая имеет больше смысла и является тем, что я ожидаю, что отладчик Visual Studio сообщит.

В этом классе определен SmoothXEnabled (из совершенно другой сборки и DLL)

public abstract class ParameterViewModel : BaseViewModel, IDisposable
{
    public virtual bool SmoothTableEnabled { get; set; }
    public virtual bool SmoothEnabled { get; set; }
    public virtual bool SmoothXEnabled { get; set; }

Если я продолжаю удалять классы из проекта, например, удаляю класс, содержащий SmoothXEnabled, отладчик выдает следующую ошибку:

System.NullReferenceException: 'Object reference not set to an
instance of an object.'container.CheckSumAddr was null.

CheckSumAddr, по крайней мере, из того же пространства имен, однако он также еще раз, даже не создается и не ссылается из класса, в который выдается NullReference. Я могу продолжать свою программу, удаляя классы и переменные, и отладчик сообщает, что случайная величина, отличная от случайного класса, каждый раз равна нулю.

Если я добавлю поле в SegmentedBinaryData, я могу сместить «случайное» поле, которое названо в исключении. Это почти как отладчик обращается к нулевому указателю, добавляя смещение (возможно, из-за индексатора?), Затем достигая другой случайной величины?

Кто-нибудь может объяснить, почему отладчик visual studio работает таким образом, а отладчик dnspy ​​- нет?

edit: Причина, по которой это важно выяснить, заключается в том, что неверное имя поля, о котором сообщается, было потрачено много времени, пытаясь выяснить, как это может быть нулевым. Если бы не было задано имя поля, я бы увидел, что StringData имеет значение null и сразу же исправил проблему. Только после отладки с помощью dnspy ​​я понял, что проблема в StringData.

...