【问题标题】:Getting NullReferenceException in impossible situation (when checking for null)在不可能的情况下获取 NullReferenceException(检查 null 时)
【发布时间】:2012-10-06 01:01:49
【问题描述】:

我在我的一种方法的开头有一个非常简单的检查,如下所示:

public void MyMethod(MyClass thing)
{
    if(thing == null)
        throw new ArgumentNullException("thing");

    //Do other stufff....
}

但是我得到了堆栈跟踪(来自生产环境中的 Elmah),这似乎表明“if(thing == null)”行正在引发 NullReferenceException。堆栈跟踪的前 2 行类似于:

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at MyLibrary.BL.AnotherClass.MyMethod(MyClass thing) in C:\Development\MyProject\trunk\MyLibrary.BL\AnotherClass.cs:line 100

MyClass 是一个相当简单的类,没有运算符重载或类似的东西,所以我对抛出 NullReferenceException 的原因有点困惑!

任何人都可以提出可能导致这种情况的场景吗?

编辑:我怀疑“事物”可能为空,但我真的希望 ArgumentNullException 而不是 NullReferenceException - 这基本上就是这个问题的意义所在。是否有框架或 Elmah 正在更改或错误报告异常 - 或者是二进制文件在某种程度上已过时的唯一解释?

【问题讨论】:

  • 您发布的错误还显示HttpUnhandledException。这是从哪里来的,--> 是什么意思?
  • 如果您刚刚添加了此检查,请确认您的站点使用最新的二进制文件。为了避免潜在的过载问题,总是有object.ReferenceEquals
  • @SimpleCoder:这只是 Elmah 的堆栈跟踪的第一行 - 我已经编辑了问题以包含下一行。注意源文件中的第 100 行是 if 语句。
  • @AntonTykhyy:不,我已经在我们的源代码控制中查看了这个文件,并且检查一直都在适当的位置......这就是我如此困惑的原因。
  • 与其依赖于抛出哪些未处理的异常并查看消息,不如调试您的应用程序并验证一切都如您所声称的那样是。

标签: c# nullreferenceexception


【解决方案1】:

if (thing == null) 不可能抛出 NullReferenceException

这意味着正在发生其他事情。是时候开始运用您的想象力了,并下定决心忽略if 引起问题的可能性。

【讨论】:

  • 这就是我害怕(和怀疑)的一种情况:)我猜当我真正了解它时,我会接受你的答案。暂时 +1。
  • 这不是真的,如果 MyClass 有 public static bool operator ==(MyClass a, MyClass b) { throw new NullReferenceException(); }
  • 不可能通过该堆栈跟踪获得NullReferenceException。对operator== 的调用将在堆栈中。
  • 接受为答案;我重建并重新部署了二进制文件,现在异常被排除在外 - 显然该站点的最后一次部署出现了问题。
  • 故事的寓意:如果在执行代码时得到NullReferenceException,并且源代码表明在堆栈跟踪中指示的行中不可能得到NullReferenceException ,那么是因为你的源代码和你正在执行的二进制代码不匹配。
【解决方案2】:

如果 MyClass 错误地定义了 == 运算符,if 语句可能会抛出 NullReferenceException,例如

class MyClass
{
   int A {get;set;}

   public static bool operator ==(MyClass a, MyClass b)
   {
      return a.A == b.A;
   }

   public static bool operator !=(MyClass a, MyClass b)
   {
      return !(a == b);
   } 
}

【讨论】:

  • 不错的想法 +1;但我确实检查了问题中提到的任何类似的东西。
  • 是的,我有一个 == 覆盖并且完全忘记了它!
【解决方案3】:

看起来异常来自调用 MyMethod 的链上的某些东西。 MyMethod() 正在抛出异常,并且上面没有处理它,所以无论您使用什么 Web 框架都会抛出 HttpUnhandledException。

【讨论】:

  • 是的,但是 OP 询问的是异常包装的 NullReferenceException
  • 他是否将空值传递给 myMethod()?如果是,则 if 语句将评估为真,并抛出该异常。如果他不是,那么 if 语句将评估为 false,并且不会抛出该异常。他是否确定他没有将空引用传递给该方法并按预期获取异常?
【解决方案4】:

我也遇到过这种不可能的情况。原来是由于使用了as 关键字,我不知道为什么。我正在使用 SharpPdf 库,并且有这样一行代码:

var destElement = annotDict.Elements["/Dest"] as PdfName;
if (destElement == null)
{
    continue;
}

如果我删除 as PdfName 部分,它会起作用。所以我现在有两个级别的代码检查:

var destElement = annotDict.Elements["/Dest"];

if (destElement == null)
{
    continue;
}

var destElementName = destElement as PdfName;
if (destElementName == null)
{
    continue;
}

【讨论】:

    【解决方案5】:

    东西是空的。

    这会导致它。

    [编辑]:这是我测试过的代码:

    protected void Button3_Click(object sender, EventArgs e)
    {
        MyMethod(null);
    }
    
    public void MyMethod(String thing)
    {
        if (thing == null)   //  This caused the exception to be thrown.
            throw new Exception("test");
    
        //Do other stufff....
    }
    

    【讨论】:

    • -1:thing == null 会如何导致NullReferenceException
    • 它在我的盒子上。我复制并粘贴了代码。它直接跳到了NullReferenceException。也许优化将代码移到了一行。尝试一下,看看您是否遇到相同的行为。 (与 2012 年相比)。等等...我会更新我的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2015-04-07
    • 2010-10-12
    • 2012-08-22
    相关资源
    最近更新 更多