【问题标题】:C# scope and visual studio debugC# 范围和 Visual Studio 调试
【发布时间】:2013-03-19 11:22:50
【问题描述】:

在使用 VS2010 调试 C# 代码时,我测试了我无法解释的奇怪行为。 使用下面非常简化的代码:

public void Go()
    {
        var test = new Random().Next(10) % 2 == 0; // Simulate various cases

        var qry = new[] { "bla", "ble", "bli", }.ToList(); // Get whole list        

        //string myString; // If declare out of scope OK
        if (test) // BreakPoint here and dragNDrop on next line
        {
            var myString = "bli"; // declare and instanciate in scope => NullReferenceException 

            qry = qry.Where( item => item == myString ).ToList(); // filter the list
        }
    }

当我尝试进入 if 范围而不用鼠标测试测试值时,myString 无法实例化并抛出 NullReferenceException。 要获得“功能”代码,我只需将 myString 声明在范围之外。 我不明白为什么 VS 不能让我跳过 if 测试,如果有人能向我解释这个奇怪的异常,我会很高兴。 谢谢

编辑: 在比较了两个 IL 代码(取决于 myString 声明的位置)之后,我可以看到 VS“不能”在生成的隐藏类上执行指令 newobj 并进行字符串值的分配在空值上。在“超出范围”声明版本中,newobj 指令从方法的开头开始。

ILCode(范围内):

IL_0041:  brtrue.s   IL_006e  // if (test)
IL_0043:  newobj     instance void ConsoleApplication5.BreakPointTest/'<>c__DisplayClass1'::.ctor()
IL_0048:  stloc.2
IL_0049:  nop
IL_004a:  ldloc.2    
IL_004b:  ldstr      "bli"
IL_0050:  stfld      string ConsoleApplication5.BreakPointTest/'<>c__DisplayClass1'::myString

我认为指针的跳转在 nop/ldloc.2 指令上完成,并且“忘记”了 c__DisplayClass1 的实例化。

【问题讨论】:

  • 您是否正在构建发布模式?发布模式下的编译器优化可以对代码做一些事情,使调试体验与你在代码中看到的有点不一致。
  • 我尝试了该代码(在调试器下),无论哪种方式对我来说都可以正常工作。
  • 也可以配合指令指针的移动?

标签: c# visual-studio-2010 debugging scope


【解决方案1】:

这看起来像是一个调试器问题。但请注意,生成的代码与您编写的代码完全不同。您在 lambda 表达式中使用 myString,因此编译器创建了一个隐藏类来存储对 myString 的引用。当您拖动指令指针时,可能会跳过此类的必要初始化,因为它们没有在您的源代码中表示。

作为一个想法,尝试在“if”之后的左括号上拖动指令指针。

【讨论】:

  • 请问这是我的第一个问题...(回车键...)。我在没有优化的调试模式下构建,当我只在左括号上拖动时:相同的结果。 @Alex:您应该有权初始化代表 lambda 的隐藏类。我会朝这个方向搜索,因为我不太了解幕后情况。
猜你喜欢
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 2017-04-15
  • 2012-01-24
相关资源
最近更新 更多