I noticed that when I view variables of certain types, such as XElement, in the Watch window in Visual Studio, if I click on the Debug Visualizers magnifying glass, the same visualizers that apply on strings (Text, XML, HTML) appear. I haven't seen this happen on any other type before. How does the debugger decide to do this?
EDIT: Here's a screenshot from the Watch window, demonstrating that XElement gets to be displayed with Text Visualizer, while System.Version (which also implements ToString) does not.
This is actually a bit of a complex question because there are multiple pieces of the expression evaluator that control the display of custom viewers.
For the Text, XML and HTML viewer the answer is pretty easy because they are visualizers built into the debugger. If IDebugProperty2::GetPropertyInfo
returns DBG_ATTRIB_VALUE_RAW_STRING
as a part of the attribute flags then this visualizer will be displayed. When the user selects on of these viewers the debugger will call back into IDebugProperty3::GetStringChars / GetStrigCharLength
in order to get the string value to pass to the visualizer.
For user defined visualizers though it is quite a bit more involved probably a bit to much for an answer here. MSDN does have a bit of information on how to do this though
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
Now lets consider the specific example called out in this question: Version
vs. XElement
. The first thing to note is that you get different behavior depending on which language you are debugging in. C#, as you noticed, shows the visualizer only for XElement
while VB.Net will show the visualizer for both XElement
and Version
. This is unsurprising in some ways because the visualizer flag is controlled by the EE and each language has their own implementation
If the value is typed to String
or has an implicit reference conversion to XNode
then the visualizer is displayed.
In this case XElement
derives from XNode
hence it gets the visualizer. The Version
type does not derive from XNode
and it's not String
so it does not get the visualizer
If the value being displayed meets one of the following then the visualizer is displayed
String
or has a ToString
override DebuggerDisplay
which points to a value that qualifies for 1 or 2 In this case both XElement
and Version
override ToString
hence the visualizer is shown in both cases
Beats me. When I wrote the VB.Net implementation I wanted to support the visualizer in as many places as possible (it's really useful). Hence whenever the final value being displayed was a String
I displayed the visualizer. I didn't really think to consult the C# team when I made this decision. Until I researched the code base to answer this question I wasn't even aware there was a difference :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With