为什么'{'在静态方法中抛出NullReferenceException?

时间:2010-08-26 13:20:20

标签: c# visual-studio winforms static nullreferenceexception

这个有点深奥。尝试在visual studio 2008中的winforms项目中打开表单(在winforms设计器中)时遇到了NullReferenceException。堆栈跟踪指向以下代码的第四行:

public static class Logger
{
    public static void LogMethodEnter()
    {
        var frame = new StackFrame(1);
        var method = frame.GetMethod();
        Trace.TraceInformation("{0}.{1}.{2}()", method.DeclaringType.Namespace, method.DeclaringType.Name, method.Name);
        Trace.Indent();
    }

    public static void LogMethodExit()
    {
        Trace.Unindent();
    }
}

...表示带有开口花括号的线条。我在其他项目上遇到了同样的问题(但不涉及winforms设计器),我认为这是一个与线程相关的问题,但我没有代码来复制它。

为什么会发生这种情况,为什么异常堆栈跟踪指向带有大括号的行?

澄清:空引用异常仅发生在winforms设计器中。运行应用程序时,它不会抛出该错误。

5 个答案:

答案 0 :(得分:4)

我猜测行号是关闭的(实际原因并不重要),这个表达式实际上抛出了异常:

method.DeclaringType.Namespace

你可能会看到NullReference异常的原因是因为前面几行的new StackFrame(1)表达式有时会返回一个空帧。空框表示对.GetMethod()的调用将返回null,然后就可以了。

您有时会得到一个空框架的原因是,即时编译器可以选择内联短的,重复调用的方法,如代码中的方法。这会抛弃你的调用堆栈,所以最好你得到一个比你想要的更高级别的方法,或者最坏的方法(在你的Main方法中)没有更高的方法,你得到null。

答案 1 :(得分:4)

我的猜测是你在类中的某个地方初始化了一个静态成员,并且该初始化程序会抛出NullReferenceException。此外,我猜你没有静态构造函数,所以你的对象被标记为beforefieldinit,因此当你使用它的方法被JIT时抛出NullReferenceException

类似的东西:

public static class Logger
{
    private static object x = InitObjectX();
    private static object InitObjectX() {
        x.GetHashCode(); // Will throw since x is null.
    }

    public static void LogMethodEnter() 
    { 
        var frame = new StackFrame(1); 
        var method = frame.GetMethod(); 
        Trace.TraceInformation("{0}.{1}.{2}()", method.DeclaringType.Namespace, method.DeclaringType.Name, method.Name); 
        Trace.Indent(); 
    } 

    public static void LogMethodExit() 
    { 
        Trace.Unindent(); 
    } 
} 

答案 2 :(得分:3)

包含行信息 .pdb文件可能已过期

要解决此问题,请重建项目并确保在项目设置中启用.pdb文件的创建。对于C#项目,可以通过设置 Advanced - >在 Build 选项卡上配置它。调试信息完整仅限pdb

答案 3 :(得分:1)

我认为问题与构造静态对象之前调用的静态方法有关。我通过添加static constructor来修复winforms项目中的问题。

如果我没记错的话,静态构造函数会在执行时锁定整个对象。

答案 4 :(得分:0)

指向一个花括号/看似错误的代码行有时会发生。我认为只是在前一行代码中发生了异常,而Visual Studio由于某种原因突出显示了下一行。

根据猜测,由于任何数量的内部和外部因素,程序可能不会在发生异常的行上完全中断。

抱歉,我无法解释这一点。