采取以下功能:
DataTable go() {
return someTableAdapter.getSomeData();
}
当我在这个函数中设置断点时,是否有可能检查返回值? go()
直接耦合到 .aspx
页面中的数据网格。
检查返回的数据表的唯一方法是使用临时变量。但是,这有点不方便。难道没有别的办法了吗?
从来没听说过。请注意,如果您确实添加了一个变量,无论如何它都会在发布版本中被编译器删除......
更新: This functionality has been added to VS2013。您可以在自动窗口中查看返回值或在监视/立即窗口中使用 $ReturnValue
。
该值只能在从函数返回后直接看到,因此访问它的最简单方法是在函数调用上放置断点并跳过 (F10) 调用。
VS2015 更新:嘘!不幸的是,它似乎不在 VS2015 (devenv v14) VS2017 更新中:它回来了。 (devenv v15)
这可以在带有 CLR 4.5.1 according to the customer feedback site 的 Visual Studio 2013 中完成。它在 C# 的早期版本中不可用。
(Visual Studio 2008 和更早的版本支持 VB.NET。它一直可供 C/C++ 开发人员使用。)
我同意这是一件非常有用的事情:不仅可以在退出之前查看方法的返回值,还可以查看我刚刚跨过的方法的返回值。我将它作为 Visual Studio 商业扩展的一部分实现,称为“OzCode”。
有了它,您可以直接在代码编辑器上查看方法返回值,就像 HUD 显示一样:
https://i.stack.imgur.com/Kw7mp.gif
有关详细信息,请参阅 this video。
根据微软的说法,没有办法通过托管代码可靠地实现这一点。这是他们意识到并正在解决的问题:
对于那些有调试本机 C++ 或 VB6 代码经验的人,您可能已经使用了在“自动”窗口中为您提供函数返回值的功能。不幸的是,托管代码不存在此功能。虽然您可以通过将返回值分配给局部变量来解决此问题,但这并不方便,因为它需要修改您的代码。在托管代码中,确定您已跨过的函数的返回值要复杂得多。我们意识到我们无法在这里始终如一地做正确的事情,因此我们删除了该功能,而不是在调试器中为您提供不正确的结果。但是,我们希望为您带来这一点,我们的 CLR 和调试器团队正在寻找一些潜在的解决方案来解决这个问题。不幸的是,这不是 Visual Studio 11 的一部分。
关于 Visual Studio 2015:
根据 Marc Gravell 目前接受的答案:
此功能已添加到 Visual Studio 2013。您可以在自动窗口中查看返回值或在监视/立即窗口中使用 $ReturnValue
该答案还指出,此功能在 Visual Studio 2015 中不起作用。这不是(完全)正确的。 Examine return values of method calls 上有以下注释:
您必须打开旧版表达式求值器才能识别 $ReturnValue(工具/选项/调试/使用旧版 C# 和 VB 表达式求值器)。否则,您可以使用 $ReturnValue1。
我在 Visual Studio 2015 Enterprise 中对此进行了测试:
关闭旧式表达式评估器:只有 $ReturnValue1 有效
打开旧式表达式求值器:$ReturnValue 和 $ReturnValue1 都有效
$ReturnValue
有效。但是,如果您启用了 Use managed compatibility mode
调试选项,则返回值不会出现在任何地方。
如果您转到菜单工具 → 选项,IntelliTrace,并更改设置以收集事件和呼叫信息。
您可以返回到上一个调用事件(Ctrl + Shift + F11),并在自动窗口中查看从方法调用返回的临时值作为方法名称的子项。
这不会向您显示您所在方法的返回值。它只是向您显示当前方法中调用的最后一个方法的返回值。
所以,这很好
DataTable go(){return someTableAdapter.getSomeData();}
因为它显示了 someTableAdapter.getSomeData()
的返回值。
但不适用于:
int go(){return 100 * 99;}
.NET 之前的老技巧:打开 Registers 窗口并查看 EAX 寄存器的值。这包含最后调用的函数的返回值。
使用 Shift-F11 退出 go() 方法,然后在“Autos”调试窗口中,它将显示刚刚从堆栈中弹出的方法调用的返回值(在这种情况下,go() 方法是你想要什么)。这是 Visual Studio 2005 中的行为;我没有使用过 Visual Studio 2008,所以我不知道这在那个版本中的行为是否相同。
是的,有一个非常好的方法。一个重要的缺点是您必须等待 5 年,甚至 6 年。既然我看到你在 2008 年 11 月发帖,我建议你 waaaaaa...
……啊啊啊。瞧!只是为了您,MS 发布了最新的 Visual Studio 2013,它是在调试模式下运行时可从菜单访问的默认功能(菜单调试 → Windows → 自动)。
有很多解决方法,但似乎没有一个令人满意。
引用下面的 John Skeet(评论现已删除的答案):
对我来说仍然看起来很不方便 - 特别是如果您在开始调试之前不知道需要哪个返回值。我真的不想每次我返回任何东西时都需要一个临时变量来弄乱我的代码。t
理论上,调试器可以有一个 return
变量。毕竟:它只是堆栈上的一个变量:
unsafe {
int * sp = stackalloc int[1];
try {
return a+b;
}
finally {
Trace.WriteLine("return is " + *(sp+3));
}
}
因此,请将此视为 Visual Studio 的功能请求。
我想扩展 PascalK's answer 以使其在 Visual Studio 2015 中工作,因为有一个隐藏功能未在 Examine return values of method calls 中记录。
如果您有嵌套的函数调用,则会自动创建伪变量 $ResultValueX
,其中 X 指的是函数调用顺序。因此,如果您有诸如 Multiply(Five(), Six())
之类的调用,则会创建以下伪变量:
Five() | $ResultValue1 = 5
Six() | $ResultValue2 = 6
Multiply() | $ResultValue3 = 30
Microsoft Visual C++ 曾经这样做,但 Visual Studio 没有 AFAIK.. :(
我知道的唯一方法是在返回行上放置一个断点,然后调用 Quick Watch 窗口并输入返回的表达式:
someTableAdapter.getSomeData();
但这仅在调用未更改任何对象的状态时才有效(因为当您恢复执行时,将对同一方法进行第二次调用)。
您也可以要求评估中间窗口中的值,如果它没有设置标志或其他变量,而只是返回一些东西。
我认为您可以通过查看 Registers 窗口(Debug / Windows / Registers)中的 RAX 寄存器来确定这一点。退出函数(SHIFT + F11)后,检查RAX寄存器。我不知道事实,但有一次你可以检查一个寄存器(.NET 之前的日子)并在那里查看返回值。它甚至可能是 RAX 和 RBX 等的组合。
打开 Debug → Autos 窗口会让你关闭。它不会显示实际的返回值,但会显示在 return 语句中评估的内容。
return x + y;
我的意思是,如果您在这一行设置断点,那么您的 Debug-Autos 窗口将显示 x 和 y 的当前值。正如我所说,它只会让你靠近。只是想提供帮助。我认为这不值得一票否决。
是的,通过切换到 VB.NET。 ;P(你刚才说的是“Visual Studio”。;)
只要我记得(从 Visual Basic 到 VB.NET 的所有版本),您就可以简单地查询函数名称。它像一个在函数开始时隐式声明的局部变量一样“起作用”,并且每当函数通过非返回语句退出时(即 Exit Function
或只是通过)和当然,当使用return语句时。
它也被设置为 return 语句的表达式。就像局部变量一样,它的值可以在函数内部的任何执行点检查(包括在执行 return 语句之后)。 C# 没有这个并且应该。
这个小小的 VB.NET 功能(加上它启用的 Exit Function
语句 - C# 没有并且应该的另一个功能)在 defensive programming 我练习的形式中非常有用,我总是将函数名称初始化为失败/默认值作为第一条语句。然后,在任何失败点(通常比成功点更频繁地发生),我可以简单地调用 Exit Function
语句(即无需复制失败/默认表达式甚至常量/变量名称)。
在 VS2019 中,只需转到 Debug->Windows->Autos 窗口。在那里,您会看到 concat 返回值,如下所示:
https://i.stack.imgur.com/ENccs.png
您可以尝试选择 "someTableAdapter.getSomeData();"
,右键单击它,然后选择 Quick Watch。
将返回表达式拖放到监视窗口中。
例如,在声明中
return someTableAdapter.getSomeData();
拖放
someTableAdapter.getSomeData()
进入监视窗口,您将看到该值。
您可以对任何表达式执行此操作。
不定期副业成功案例分享