Visual Studio 内置有如此之多有用的调试特性,但并非众所周知。本文列举一些我的最爱,包括最近我在 VS2013 中发现的调试特性。
1. 在 Lambda 表达式中的断点
如果你点击左边栏设置断点,你可能很容易被误导认为断点发生在行级别上。实际上,你可以在行内部插入断点,如在你的 LINQ 的 Lamdba 表达式中。仅需右击代码部分并且从菜单选择 Breakpoint > Insert breakpoint。
2. 便捷的输出窗口
输出窗口对调试很有用,同样断点也是弹出式或中断程序的,但它确实很嘈杂。仅需右击输出窗口(要确保输出被设为调试),关闭 Module Load,Module Unload,Process Exit 和 Thread Exit 以只输出你关心的内容。现在用 Debug.WriteLine 给出你真正关心的内容吧。
你也可以在输出窗口使用 Ctrl-S 保存设置。
3. 在客户端和服务器端附加调试(VS2012)
服务器端和客户端工程在一个 solution 中是有用的,你仅需要一份 Visual Studio 运行时拷贝而且也不会在 alt-tab 键的前进后退中迷失,特别是当它们使用共同的代码如数据结构工程。
有一个缺点,start-up 工程是唯一获得附加调试的工程。如果你遇到异常,它会显示在你的客户端,而不是服务端。
现在这个问题很容易解决了。右击 solution,选择 properties > Multiple startup projects,然后选择 Start 动作为你需要附加调试的工程。
4. 创建可重建工程模板
如果你负责 SDK 或者 API,创建一个你独用的简单的应用程序。然后使用 File > Export template 保存它。
现在你随时可以从你的模板创建一个新的工程,仅需要一些点击。更好的做法是使得用户和测试者能够使用它们,以便他们给你最小的重建。
5. 使用 DebuggerDisplay 属性
调试器默认会使用 ToString ()来监视并在窗口正常输出类名。即使你重写 ToString,对其他调试者也不见得一目了然。
在你的类中通过一句简单的表达式,而不是改变属性值来使用 DebuggerDisplay。例如:
[DebuggerDisplay ("Order {ID,nq}") class Order { public string ID { get { return id; } } }
“nq”阻止了双引号发散。你也可以在这里使用方法,但是别做任何可能带来微小副作用的事,否则你观察的对象可能改变其行为,并导致奇怪的事发生。
6. 管理断点
你创建了一些带劲的断点,现在你要关闭其中的一个,因为它被点击了太多次,但你马上又要再次用到它。如果你删除了这个断点,你就不得不回来再找到断点位置。
打开常被忽视的 Breakpoints 窗口(Ctrl-Alt-B)。这个窗口显示了你设置的所有的断点但关键的是允许你使它们无效仅仅通过去除 check 标记。再次 check 上以重新使它有效。
这个窗口同样提供了快速调试的功能:
- 条件 断点什么时候发生
- 发生次数 观察多长时间发生一次并基于该次数中断
- 标签 断点在分支中允许有效和无效
- 何时发生 在输出窗口显示一条消息以代替真实的中断
7. 断开或输出调用者信息(.NET 4.5/Windows 8 Store)
没有为调用程序当前方法准备的全局变量,并且得到当前栈内容是一个非常慢的操作。
一个快速简单的手段是,为方法增加一个额外的可选字符型参数了,用 CallerMemberName 属性。例如,
void MyFunction (string someValue, [CallerMemberName] string caller = null) { ... }
因为这是可选的值,你不必修改任何调用程序,但现在你能:
①基于调用程序变量,在某些程序中设置断点条件
②向日志文件或者输出窗口输出调用程序内容
你也可以使用 CallerLineNumber 和 CallerFilePath。同样记住构造函数,终结器和运算符重载将会显示它们的相关方法名(.ctor,op_Equals 等等)。
8. 监视方法返回值(VS2013, .NET 4.5/Windows 8.1 Store)
有时你想看看方法返回值但对你来说并不容易,因为它是另一个方法的输入参数,所以你并没有存储该值。
这个功能被加到 VS2013 中,但是它却非常容易错过,你不得不在正确的时间和正确的地方使用它。正确的地方是 Autos 窗口,正确的时间是刚好回到方法被调用的地方这一步。当在你调用方法之前或者在方法体中时你看不到这个。它是一个单一步骤,像这样:
箭头标明它是返回值,并且让你知道和它相关的方法名。
写在最后
我也不得不强调,一旦软件离开了你的机器,记录日志对问题解决是多么有效。但这是一个比这个更大的议题。
我是不是遗漏了一些更好的调试建议?在下面的回复中随时让我知道吧。
附:Michael Parshin 也有一些调试的很棒的建议。