【问题标题】:Why can't the debugger/runtime tell me which object is null?为什么调试器/运行时不能告诉我哪个对象为空?
【发布时间】:2014-05-29 14:34:50
【问题描述】:

代码:

items.FirstOrDefault(x => x.Foo.Bar.BarId == snuh.BarId);

错误:

System.NullReferenceException:对象引用未设置为实例 一个对象。

空对象可以是itemsFooBarsnuh

调试器/运行时可以告诉我错误发生在哪一行代码上。为什么它也不能告诉我是哪个对象有问题?

注意:我知道我可以调试它并找出答案。 Visual Studio 无法向我提供违规对象的名称是否有原因?

【问题讨论】:

  • 我认为这可能与这篇关于 Lampba 表达式的帖子以及您无法调试它们的事实有关:*.com/questions/725499/…
  • 其实x也可以为null。许多集合允许您将 null 作为项目添加到列表中。
  • 空引用由不知道是什么对象生成空引用的代码检测到。这就像说当您执行 sqrt(x) 并且 x 为负数时,sqrt 函数应该说“不能对变量 x 中的负数取平方根”。

标签: c# visual-studio debugging visual-studio-2013 nullreferenceexception


【解决方案1】:

因为调试器或编译器有源符号,所以它们可以将名称映射到地址。

但是,运行时不知道引用在您的源代码中是如何命名的(它已被编译)。

请注意,如果您(不是 CLR)抛出 NullReferenceException,那么您可以在嵌入消息中添加任何信息。

【讨论】:

  • +1 这个答案,因为它提到如果你要抛出异常,你可以通过try.. catch... 块添加你自己的关于哪个对象为空的信息以及一个很好的解释。
  • 但是当我在调试器中运行时呢?调试器不应该能告诉我吗?
  • @BobHorn - 调试器收到一个异常,可以确定它来自哪一行(如果幸运的话)。它可以确定该行的哪个 part 导致异常的唯一方法是重新运行每个部分并插入额外的NULL 检查 - 但假设该行是确定性的并且不会导致副作用, 并且调试器不这样做并安全运行会更安全。
【解决方案2】:

由于优化等原因,“此引用存储在寄存器R22/位于堆栈槽5”与实际获取该引用的方式之间的关系很难推断。

目前它只知道有人试图取消引用它,结果是NULL

通常,它试图取消引用的内容可能在源代码中也没有清晰/易于理解的名称。

【讨论】:

    【解决方案3】:

    对于大多数语言来说,接收空指针但不指定对象是很常见的。我很确定它是因为它一开始就找不到对象来告诉你它是什么。

    【讨论】:

    • 如果找不到对象怎么知道它是空的?
    • 因为它在它所指向的内存地址上找不到任何东西。
    最近更新 更多