在使用 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 的实例化。