C# 此代码如何引发NullReferenceException?

C# 此代码如何引发NullReferenceException?,c#,nunit,C#,Nunit,我一定是疯了,因为我的单元测试失败了,因为下面的代码引发了null ref异常: int pid = 0; if (parentCategory != null) { Console.WriteLine(parentCategory.Id); pid = parentCategory.Id; } 这句话的意思是: pid = parentCategory.Id; writeline仅用于在NUnit GUI中调试,但它会输出有效的int 编辑:它是单线程的,因此不能从其他线程

我一定是疯了,因为我的单元测试失败了,因为下面的代码引发了null ref异常:

int pid = 0;
if (parentCategory != null)
{
    Console.WriteLine(parentCategory.Id);
    pid = parentCategory.Id;
}
这句话的意思是:

pid = parentCategory.Id;
writeline仅用于在NUnit GUI中调试,但它会输出有效的int

编辑:它是单线程的,因此不能从其他线程将其分配给null,并且Console.WriteLine成功打印出该值表明它不应该抛出

编辑:类别类的相关代码段:

public class Category
{
    private readonly int id;

    public Category(Category parent, int id)
    {
        Parent = parent;
        parent.PerformIfNotNull(() => parent.subcategories.AddIfNew(this));
        Name = string.Empty;
        this.id = id;
    }
    public int Id
    {
        get { return id; }
    }
}
如果有人想看完整的代码,可以在

我想我要试着重新启动电脑。。。我见过通过重启修复的非常奇怪的事情。将在重新启动后更新


更新:谜团已经解开。看起来NUnit将错误行显示为最后一条成功执行的语句。。。将测试复制/粘贴到新的控制台应用程序中,并在VS中运行,结果表明,正是if语句块(未显示)后的一行包含空引用。感谢大家的所有想法+1致所有回答的人。

是的,我们能看看分类类的代码吗。。特别是Id属性?假设Id属性是一个int(而不是一个可为NULL的int),get方法必须访问一个NULL对象。

但没有意义的是,OP声明console.writeline输出一个有效的int,并且它调用与他声明抛出错误的行相同的属性


stacktrace会很有帮助,或者可以查看实际的单元测试。

Id可以是一个无值的可为null的int类型(int?),但是我觉得属性Id必须做的不仅仅是返回一个int,以及其中的null


编辑您的编辑揭示了这一点非常奇怪,您能为我们提供堆栈跟踪吗?

根据目前为止的所有信息,我认为要么“抛出的线是”是错误的(是什么让您这么认为的),要么您的“源”与您构建的程序集不同步


这看起来是不可能的,所以一些“理所当然的假设”是错误的,这可能是假设“您正在查看的源代码与您正在调试的进程相匹配”。

我不是C#方面的专家,也不确定这是否会产生影响,但您是在调试模式下调试,还是在发布模式下调试?如果你处于发布模式,你的IDE指向的行和问题所在的线路可能不同(我知道C++中使用Visual Studio时的情况)

< P>我必须同意布瑞恩的观点…可能您使用的是过时的.pdb,并且在调试模式下看到的代码与实际调试的代码不一致


尝试清理项目,并在调试模式下重建它

当事情表面上看是对的,那么你很可能会忽略它。您是否有350%的把握认为您的DLL/PDB与源代码匹配,从而为您提供了正确的行

  • 尝试手动删除程序集并运行正在运行的任何程序集。它是否应该失败
  • 尝试清理解决方案并重新编译。将程序集复制到任何位置,然后再次运行它。这次有用吗?同一地点的空参考
  • 调试周围的行以获得所需的值。parentCategory等应该符合您的想法
  • 通过引发异常来修改代码。堆栈跟踪行是否与代码中的行完全匹配

我有过一些非常令人难以置信的经历,就像这样,因为我的一个假设是错误的。典型的是陈旧的组件。质疑所有假设。

看起来NUnit将错误行显示为最后一条成功执行的语句。。。将测试复制/粘贴到新的控制台应用程序中,并在VS中运行,结果表明,正是if语句块(未显示)后的一行包含空引用。感谢大家的所有想法+1致所有回答的人。

什么类型是parentCategory和Id?有隐式运算符吗?有关系吗?它被检查为null,它是单线程的,属性被正确访问,因为Console.WriteLine成功。Id的类型是int。除非您在Id属性中执行某些关联操作,否则此代码应该可以正常执行。不知怎的,我觉得你没有告诉我们整个故事。根据我的经验,这种“不可能”的事情往往是由一些微妙的语法错误造成的,比如忘记了大括号、括号或分号。@Svante但编译器应该捕捉(大部分)这些东西不?@Brian,你不认为如果他有不匹配的代码VS会给他一个警告吗?@Vadim:我可能没有看到,但我没有看到线程上的证据表明他甚至必须使用VS。如果代码和程序集之间存在不匹配。他如何调试它?然而,这仍然向我们展示了控制台。WriteLine(parentCategory.Id);正在抛出空值。什么原因?我将if'后面的'line interepret'设置为if'块的紧密卷曲后的'mean'行,例如,OP从未向我们显示的某些代码。@lagerdalek-如果NUnit显示最后一个成功的行,并且显示pid=parentCategory.Id;,然后是Console.WriteLine(parentCategory.Id);会很顺利的。断开的那一行是pid=…,Davy8没有向我们显示(这并不重要)对,我指的是if块后面没有显示的那一行。我以前肯定见过这种情况。这次不是这样,但一定要检查一下