我注意到,当我在 Visual Studio 的 Watch 窗口中查看某些类型的变量(例如XElement)时,如果我单击 Debug Visualizers 放大镜,则会出现适用于字符串(Text、XML、HTML)的相同可视化工具。我以前从未在任何其他类型上看到过这种情况。调试器如何决定这样做?
编辑:这是 Watch 窗口的屏幕截图,展示了 XElement 可以使用 Text Visualizer 显示,而 System.Version(也实现了 ToString)没有。
我注意到,当我在 Visual Studio 的 Watch 窗口中查看某些类型的变量(例如XElement)时,如果我单击 Debug Visualizers 放大镜,则会出现适用于字符串(Text、XML、HTML)的相同可视化工具。我以前从未在任何其他类型上看到过这种情况。调试器如何决定这样做?
编辑:这是 Watch 窗口的屏幕截图,展示了 XElement 可以使用 Text Visualizer 显示,而 System.Version(也实现了 ToString)没有。
这实际上是一个有点复杂的问题,因为有多个表达式评估器控制自定义查看器的显示。
对于文本、XML 和 HTML 查看器,答案非常简单,因为它们是内置于调试器中的可视化工具。如果作为属性标志的一部分IDebugProperty2::GetPropertyInfo
返回DBG_ATTRIB_VALUE_RAW_STRING
,则将显示此可视化工具。当用户选择这些查看器时,调试器将回调IDebugProperty3::GetStringChars / GetStrigCharLength
以获取要传递给可视化器的字符串值。
对于用户定义的可视化工具,虽然它涉及的内容要多得多,但这里的答案可能有点多。MSDN 确实有一些关于如何做到这一点的信息
http://msdn.microsoft.com/en-us/library/vstudio/bb162331(v=vs.100).aspx http://msdn.microsoft.com/en-us/library/vstudio/bb146621(v= vs.100).aspx
现在让我们考虑一下这个问题中提到的具体例子:Version
vs XElement
. . 首先要注意的是,根据调试的语言,您会获得不同的行为。正如您所注意到的,C# 仅显示可视化器,XElement
而 VB.Net 将同时显示XElement
和Version
. 这在某些方面并不令人惊讶,因为可视化标志由 EE 控制,并且每种语言都有自己的实现
如果该值被键入String
或具有隐式引用转换,XNode
则显示可视化工具。
在这种情况下,它XElement
派生自XNode
因此它得到了可视化工具。该Version
类型不是派生自XNode
,也不是String
,所以它没有得到可视化工具
如果显示的值满足以下条件之一,则显示可视化工具
String
或有一个ToString
覆盖DebuggerDisplay
指向符合 1 或 2 条件的值在这种情况下,两者都XElement
覆盖,Version
因此ToString
可视化工具在两种情况下都显示
打败我。当我编写 VB.Net 实现时,我想在尽可能多的地方支持可视化器(它真的很有用)。因此,每当显示的最终值是 a 时,String
我都会显示可视化工具。当我做出这个决定时,我并没有真正考虑咨询 C# 团队。在我研究代码库来回答这个问题之前,我什至不知道有什么不同:)
调试器如何决定这样做?
它有一个可视化工具注册表,具体取决于对象类型。
你可以自由地写你自己的。
如果您没有看到可视化工具,则根本没有注册。并且 VS 带有一些很好的标准。