如何在没有返回变量的情况下调试VB.NET计算函数返回值

4
通常情况下,我可以编写一个很好的VB.NET函数,但当到达Return语句时,直接返回快速计算或方法调用的结果是非常自然的。 然而,如果需要通过调试器查看此函数将返回什么,这会变得困难。 例如,以这个简单的方法来说明这个概念:
Public Shared Function GetAge(ByVal dob As DateTime, ByVal asOfDate As DateTime) As Integer
   If asOfDate.Date < dob.Date Then Return 0
   Dim factor = If(asOfDate.DayOfYear < dob.DayOfYear, 1, 0)
   ' What's going to be returned?
   Return asOfDate.Year - dob.Year - factor ' Imagine that this could be a more complicated calc, or one with side-effects that would prevent me from running it in the immediate window
End Function

我发现自己改变了编写代码的方式,只是为了使调试更容易。所以该方法将变为:

Public Shared Function GetAge(ByVal dob As DateTime, ByVal asOfDate As DateTime) As Integer
   If asOfDate.Date < dob.Date Then Return 0
   Dim factor = If(asOfDate.DayOfYear < dob.DayOfYear, 1, 0)
   Dim result = asOfDate.Year - dob.Year - factor ' I made this variable just for setting a debugging breakpoint
   Return result ' I can now set a breakpoint here, but it seems awkward
End Function

调试器中是否有我忽略的功能,可以更轻松地查看方法返回的结果,而不必总是创建一个“result”变量或返回到调用者查看结果?改变代码编写方式只为了使简单的调试任务更容易似乎很麻烦 - 我感觉可能漏掉了某些东西。

3个回答

4

您可以在End Function行设置断点,并将光标悬停在函数名称上。


似乎不起作用。 在C#中也尝试了它。 我正在使用VS 2010。你能提供更多细节吗? - mattmc3
2
"本地变量" 窗口包括一个与函数同名的变量。在 "End Function" 时,这个本地变量将被设置为即将返回的值。 - Tim Murphy
太棒了,Tim!这就是我需要的。请将此作为答案发布,而不是评论,以便你能得到积分。还有一件事 - 这个解决方案只适用于VB(虽然我提问时就是这样说的)。那么在C#中该如何处理,因为函数名不会显示在本地窗口中? - mattmc3
1
也许在VS2010中他们禁用了它。那太遗憾了。在VS2008中,它可以像我描述的那样工作。请参见截图 - GSerg
还没有得到VS2010。反正在2008上也能工作。 我建议你去connect.microsoft.com并将其报告为错误。也许它已经存在了。 - GSerg

1

是的,这很尴尬。Visual Studio 6可以做到这一点,但在后来的版本中丢失了。实现起来并不容易,托管代码如何返回值是JIT编译器的实现细节。对于简单的返回值类型,如整数或对象,这似乎很明显,但当方法返回结构或十进制数时,它变得复杂。

将其先存储在变量中并没有什么问题,在大多数情况下,JIT优化器会消除该变量。但是,是的,在源代码中看起来很丑陋。

如果返回值类型很简单,比如整数,有一个技巧可以使用。在End Function语句上设置断点,然后使用Debug + Windows + Registers显示CPU寄存器值。EAX寄存器包含该值。右键单击窗口,选择浮点数。ST0寄存器包含32位模式下的浮点返回类型值。

虽然不是很好,但在紧急情况下可以解决问题。


谢谢,汉斯。EAX寄存器的东西很棒。我以前从没用过。这个值是十六进制的,只适用于数字返回类型,并且即使是如此也很残酷。但还是很不错的技巧。 - mattmc3

0
我倾向于更进一步,删除函数第一行的Return 0,这样你的代码只有在结尾处退出函数。
Public Shared Function GetAge(ByVal dob As DateTime, ByVal asOfDate As DateTime) As Integer
   Dim result = 0
   If asOfDate.Date >= dob.Date Then
      Dim factor = If(asOfDate.DayOfYear < dob.DayOfYear, 1, 0)
      result = asOfDate.Year - dob.Year - factor
   End If
   Return result
End Function

以这种方式完成,您只需要担心一个退出点 - 这使得理解您的代码更容易,因此调试更少 - 并且您可以免费获得断点!

3
这实际上是一种主观风格问题。很多计算机科学课程都教授只有一个出口点的编写方法,我的课程也是如此。但在现实世界中,我发现将特殊情况和前提条件放在方法的顶部更容易实现。这样,在方法的内部,您就可以对变量做出一定的保证。无论如何,这个问题与特定的代码片段无关,而是关于debugging需要有一个结果变量的概念。 - mattmc3
@mattmc3 - 你说得很对,我的回答有点离题了。谢谢。 - Enigmativity
我不会提供无用的答案,但这是VB,所以result是不需要的,你已经有GetAge可用! - Mark Hurd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接