Visual Studio 2017调试器使用C# Array.ConvertAll时变量不可见问题咨询
调试Array.ConvertAll时无法查看闭包变量的问题
我之前也遇到过完全一样的情况!这其实是Visual Studio 2017调试器对闭包变量的处理限制导致的,跟代码逻辑本身无关。
先看你提供的有问题的代码:
public static void Test() { Vector3[] OriginalArray = new Vector3 [3]{ new Vector3(1,2,3), new Vector3(4, 5, 6), new Vector3(7, 8, 9)}; int[] Indices = new int[2] { 2, 1}; Vector3[] SelectedArray = Array.ConvertAll(Indices, index => OriginalArray[index]); }
当你在这个lambda表达式的OriginalArray[index]处设置断点时,调试器的「本地」「自动」「监视」窗口里根本找不到OriginalArray——哪怕它确实存在于外层作用域,代码也能正常执行。
而改用foreach循环的写法时:
public static void Test2() { Vector3[] OriginalArray = new Vector3[3] { new Vector3(1, 2, 3), new Vector3(4, 5, 6), new Vector3(7, 8, 9) }; int[] Indices = new int[2] { 2, 1 }; List<Vector3> subverticesList = new List<Vector3>(); foreach (int index in Indices) { subverticesList.Add(OriginalArray[index]); } Vector3[] SelectedArray = subverticesList.ToArray(); }
在循环内设置断点,OriginalArray就能正常出现在调试窗口中。
原因分析
这是因为C#编译器处理作为参数传递的lambda表达式时,会把外层作用域的闭包变量(比如这里的OriginalArray)包装到一个自动生成的匿名类里。而Visual Studio 2017的调试器对这种匿名类的变量展示支持不完善——它不会自动将匿名类中的变量映射回原来的变量名,所以你在常规窗口里看不到它。
解决办法
- 临时调试技巧:在「监视」窗口手动输入自动生成的匿名类变量路径(比如
<>c__DisplayClass0_0.OriginalArray,具体类名可以在调试器的「局部变量」窗口里找到对应的匿名类实例),就能查看变量的值。 - 代码写法调整:像你已经做的那样,用foreach循环替代
Array.ConvertAll,虽然代码稍长,但调试体验更直观;或者把lambda逻辑抽成一个显式的静态方法,这样调试时变量会更清晰。 - 升级调试环境:升级到Visual Studio 2019及以上版本,后续版本的调试器对闭包变量的展示做了优化,这个问题会直接解决。
内容的提问来源于stack exchange,提问作者isgoed
相关产品推荐
相关产品推荐

