在Visual Studio中调试时返回之前可以找到返回值吗?

doe*_*man 373 c# visual-studio visual-studio-debugging

采取以下功能:

DataTable go() {
    return someTableAdapter.getSomeData();
}
Run Code Online (Sandbox Code Playgroud)

当我在此函数中设置断点时,是否有可能检查返回的值?go()直接耦合到.aspx页面中的数据网格.

检查返回的数据表的唯一方法是使用临时变量.但是,这有点不方便.不是有另一种方式吗?

Mar*_*ell 260

从来没听说过.请注意,如果您确实添加了一个变量,那么编译器会在发布版本中删除它...

更新: 此功能已添加到VS2013.您可以在自动窗口中查看返回值,也可以$ReturnValue在监视/即时窗口中使用.

该值只能在从函数返回后直接看到,因此访问它的最简单方法是在函数调用上放置一个断点并跳过(F10)调用.


VS2015更新:嘘!不幸的是,它似乎没有出现在VS2015的VS2015(devenv v14)
更新中:它又回来了.(devenv v15)

  • 放弃临时性的原因是可读性和风格,而不是效率,不是吗? (12认同)
  • 从VS 2010开始使用IntelliTrace:http://blogs.msdn.com/b/habibh/archive/2009/10/23/using-intellitrace-to-view-the-return-value-of-a-vb -or-C-method.aspx (8认同)
  • .NET 6 / VS 2022:似乎不起作用(自动窗口和 Watch 中的 $ReturnValue/$ReturnValue1/$returnvalue 都没有)... (7认同)
  • 我要指出的是,在 VS2019 中(至少),智能感知建议 $returnvalue 全部小写。但它区分大小写。 (6认同)
  • @MarcGravell for VS2015:$ ReturnValue1有效!(在最终版本中测试) (4认同)
  • 在 Visual Studio 2022 中,监视窗口中的名称 $ReturnValue 有效,但需要在点击“return”语句之前而不是之后将其添加到监视窗口。 (4认同)
  • @orip 有多种原因不修改代码,例如;这不是你的代码,它是一次性调试,再次单步调试需要很长时间。(这就是我无论如何都要查这个问题的原因:-) (2认同)
  • Intellitrace仅适用于VS Ultimate Edition. (2认同)
  • @MarcGravell你的回答是**错了**!当然,我的回复和MS在VS13中发布该功能花了我六年时间,但仍然如此.如果你只是添加了"*暂时*"作为免责声明...(不,我没有迟钝.当然,这只是一个笑话.你是上帝般的,伙计.) (2认同)
  • 请参阅我对VS2015支持的回答 (2认同)
  • 这是有关$ ReturnValue1支持的文档的链接-https://msdn.microsoft.com/zh-cn/library/dn323257.aspx (2认同)
  • @MarcGravell 它是 VS2019 上的 $returnvalue (全部小写)。$ReturnValue 不再有效。 (2认同)

Ale*_*gas 58

这可以在Visual Studio 2013中使用CLR 4.5.1 根据客户反馈站点完成.它在以前的C#版本中不可用.

(Visual Studio 2008及更早版本支持VB.NET.它一直供C/C++开发人员使用.)


Ome*_*viv 24

我同意这是一个非常有用的东西:不仅在退出之前看到方法的返回值,而且还看到我刚刚步过的方法的返回值.我将它实现为Visual Studio的商业扩展的一部分,名为" OzCode ".

有了它,您可以在代码编辑器上查看方法返回值,作为HUD显示的一种:

声明可视化

有关详细信息,请参阅此视频.


Dan*_*vay 22

据微软称,没有办法用托管代码可靠地实现这一点.这是他们意识到并且正在努力解决的问题:

对于那些有调试本机C++或VB6代码经验的人,您可能已经使用了一个功能,在Autos窗口中为您提供了函数返回值.不幸的是,托管代码不存在此功能.虽然您可以通过将返回值分配给局部变量来解决此问题,但这并不方便,因为它需要修改代码.在托管代码中,确定您已经跨越的函数的返回值是非常棘手的.我们意识到我们无法在此处一致地执行正确的操作,因此我们删除了该功能,而不是在调试器中给出错误的结果.但是,我们希望为您带来这一点,我们的CLR和调试器团队正在研究这个问题的一些潜在解决方案.不幸的是,这不会是Visual Studio 11的一部分.

https://connect.microsoft.com/VisualStudio/feedback/details/597933/add-a-return-pseudo-variable-to-the-visual-studio-debugger-for-net-code


Pas*_*alK 20

根据Marc Gravell目前接受的答案:

功能已添加到Visual Studio 2013中.您可以在autos窗口中查看返回值,或在watch/immediate窗口中使用$ ReturnValue

该答案还表明此功能在Visual Studio 2015中不起作用.这不是(完全)真实的.在检查方法调用的返回值时,有以下注释:

您必须打开旧版表达式计算器才能识别$ ReturnValue (工具/选项/调试/使用旧版C#和VB表达式计算器).否则,您可以使用$ ReturnValue1.

我在Visual Studio 2015 Enterprise中对此进行了测试:

  • 关闭传统表达式求值器:只有 $ ReturnValue1有效
  • 与传统表达评价者打开: $返回值 $ ReturnValue1工作

  • 这似乎不再是必要的.在VS 2015 Update 3上,我禁用了旧版评估程序,并且`$ ReturnValue`正常工作.但是,如果启用了"使用托管兼容性模式"调试选项,则返回值不会出现在任何位置. (3认同)

小智 13

如果您转到菜单工具选项,IntelliTrace,并更改设置以收集事件和呼叫信息.

您可以返回上一个调用事件(Ctrl+ Shift+ F11),并在autos窗口中查看从方法调用返回的临时值,作为方法名称的子项.

这并没有显示您所在方法的返回值.它只显示当前方法中调用的最后一个方法的返回值.

所以,这很好

DataTable go(){return someTableAdapter.getSomeData();}
Run Code Online (Sandbox Code Playgroud)

因为它显示了返回值someTableAdapter.getSomeData().

但不适用于:

int go(){return 100 * 99;}
Run Code Online (Sandbox Code Playgroud)


Col*_*inM 12

.NET .NET之前的旧技巧:打开Registers窗口,查看EAX寄存器的值.它包含最后一个被调用函数的返回值.


Leo*_*Hat 9

使用Shift-F11退出go()方法,然后在"Autos"调试窗口中,它将显示刚从堆栈中弹出的方法调用的返回值(在本例中,go()方法是你想要什么).这是Visual Studio 2005中的行为; 我没有使用Visual Studio 2008,所以我不知道这个版本的行为是否相同.

  • @LeopardSkinPillBoxHat:不,它在C#中没有这样做.PS哇,我花了一段时间才看到这个. (2认同)

Kon*_*ten 7

是的,有一种非常好的方式.一个重要的缺点是你必须等待5年,也许6年.因为我看到你在2008年11月发布,我建议你waaaaaa ...

... aaaait.瞧!只为你,MS发布了最新的Visual Studio 2013,它是一个默认功能,可以在调试模式下运行菜单(菜单DebugWindowsAutos).


doe*_*man 5

有很多变通方法,但似乎没有一个令人满意.

引用下面的John Skeet(评论现已删除的答案):

仍然看起来不方便 - 特别是如果你不知道在开始调试之前你需要哪个返回值.每次我退回任何东西时,我真的不想让一个临时变量混乱我的代码

从理论上讲,调试器可以有一个return变量.毕竟:它只是堆栈中的变量:

unsafe {
  int * sp = stackalloc int[1];
  try {
    return a+b;
  }
  finally {
    Trace.WriteLine("return is " + *(sp+3));
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,请考虑这是Visual Studio的功能请求.


spl*_*tms 5

我想扩展PascalK 的答案,以使其在 Visual Studio 2015 中工作,因为有一个隐藏功能未记录在检查方法调用的返回值中

如果您有嵌套的函数调用,$ResultValueX则会自动创建伪变量,其中 X 指的是函数调用顺序。因此,如果您有诸如 之类的调用Multiply(Five(), Six()),则会创建以下伪变量:

Five()     | $ResultValue1 = 5
Six()      | $ResultValue2 = 6
Multiply() | $ResultValue3 = 30
Run Code Online (Sandbox Code Playgroud)