抛出NullReferenceException时,C#调试器报告错误的字段名称为null

时间:2019-04-23 09:06:17

标签: c# debugging nullreferenceexception

我有一个非常奇怪的情况,我在类中尝试访问一个空参数(并因此导致出现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的类中实例化或引用。我可以继续检查程序,以删除类和变量,并且调试器每次都会报告一个与随机类不同的随机变量,而该类每次为null。

如果将字段添加到SegmentedBinaryData中,则可以移动在异常中命名的“随机”字段。几乎就像调试器正在访问“空”指针,添加偏移量(可能是因为索引器?)然后到达另一个随机变量?

谁能解释为什么Visual Studio调试器以这种方式执行,而dnspy调试器却没有?

edit:之所以要解决此问题很重要,是因为报告了错误的字段名,这浪费了很多时间,试图追踪该字段名可能为空。如果没有给出任何字段名,我会发现StringData为null并立即解决了该问题。直到我使用dnspy调试后,我才意识到StringData实际上是问题所在。

0 个答案:

没有答案