c#作用域和visual studio调试

本文关键字:studio 调试 visual 作用域 | 更新日期: 2023-09-27 18:04:34

在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,并且字符串值的赋值是在null值上进行的。在"超出作用域"声明版本中,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调试

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

作为一个想法,可以尝试将指令指针拖到"if"后面的左括号上。