{"id":225613,"date":"2019-06-10T09:00:03","date_gmt":"2019-06-10T16:00:03","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/visualstudio\/?p=225613"},"modified":"2019-06-10T09:06:56","modified_gmt":"2019-06-10T16:06:56","slug":"customize-object-displays-in-the-visual-studio-debugger-your-way","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/customize-object-displays-in-the-visual-studio-debugger-your-way\/","title":{"rendered":"Customize object displays in the Visual Studio debugger YOUR way"},"content":{"rendered":"<p>Have you ever stared at objects in a debugger window and wished that you could view those objects by something other than their type?\u00a0 I certainly have!\u00a0 Expanding items to determine each one&#8217;s identity can become tiresome very fast. Ideally, it would be great to quickly locate them by a particular property value.\u00a0 Luckily for us, Visual Studio has two not-so-well-known attributes known as <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/using-the-debuggerdisplay-attribute?view=vs-2019\"><strong>DebuggerDisplay<\/strong><\/a> for managed users, and <strong><a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/create-custom-views-of-native-objects?view=vs-2019\">Natvis<\/a><\/strong> for native C++ users. These attributes let you customize how you view objects in debugger windows such as the Watch, Autos, Locals, and datatips!<\/p>\n<p><figure id=\"attachment_225621\" aria-labelledby=\"figcaption_attachment_225621\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225621 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BeforeAfterDebugDisplay.png\" alt=\"Locals and DataTips windows with and without DebuggerDisplay attribute appended to code\" width=\"1512\" height=\"841\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BeforeAfterDebugDisplay.png 1512w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BeforeAfterDebugDisplay-300x167.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BeforeAfterDebugDisplay-768x427.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BeforeAfterDebugDisplay-1024x570.png 1024w\" sizes=\"(max-width: 1512px) 100vw, 1512px\" \/><figcaption id=\"figcaption_attachment_225621\" class=\"wp-caption-text\"><em>Figure 1 &#8211; Locals and DataTips windows with and without DebuggerDisplay attribute appended to code<\/em><\/figcaption><\/figure><\/p>\n<h4><\/h4>\n<h4>What is the DebuggerDisplay attribute?<\/h4>\n<p>By writing DebuggerDisplay syntax at the top of a class, you can choose what strings and properties you want at the top of each object node in debugger windows.\u00a0 Besides displaying strings in debugger windows, adding curly brackets ({}) to the DebuggerDisplay attribute allows Visual Studio to display the value of a property or method that you specify. You can also add <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/format-specifiers-in-csharp?view=vs-2019\">format specifiers<\/a> to DebuggerDisplay in order to further change how values are displayed and formatted in the debugger windows. In Figure 2, DebuggerDisplay appends the format specifier \u201cnq\u201d (no quotes).\u00a0 The resulting display shows the string property <em>Title <\/em>without the surrounding quotation marks.<\/p>\n<p><figure id=\"attachment_225620\" aria-labelledby=\"figcaption_attachment_225620\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225620 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDSyntax.png\" alt=\"Basic DebuggerDisplay syntax added to top of Book class\" width=\"1360\" height=\"378\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDSyntax.png 1360w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDSyntax-300x83.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDSyntax-768x213.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDSyntax-1024x285.png 1024w\" sizes=\"(max-width: 1360px) 100vw, 1360px\" \/><figcaption id=\"figcaption_attachment_225620\" class=\"wp-caption-text\"><em>Figure 2 &#8211; Basic DebuggerDisplay syntax added to top of Book class<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225619\" aria-labelledby=\"figcaption_attachment_225619\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225619 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDLocals.png\" alt=\"Locals window with above DebuggerDisplay syntax added to code\" width=\"1424\" height=\"508\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDLocals.png 1424w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDLocals-300x107.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDLocals-768x274.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/BasicDDLocals-1024x365.png 1024w\" sizes=\"(max-width: 1424px) 100vw, 1424px\" \/><figcaption id=\"figcaption_attachment_225619\" class=\"wp-caption-text\"><em>Figure 3 &#8211; Locals window with above DebuggerDisplay syntax added to code<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>One previous workaround for performing this task is overriding a class\u2019s ToString() method.\u00a0 In contrast, DebuggerDisplay controls how an item is displayed <em>without\u00a0<\/em>overriding that method.\u00a0 So, if you don&#8217;t want debugging-related content in your ToString() method (especially when that method is called in your actual program), DebuggerDisplay is the way to go!<\/p>\n<p>&nbsp;<\/p>\n<h4>Can I display expressions for each object in debugger windows?<\/h4>\n<p>There may be times when you want to display expressions in debugger windows.\u00a0 Good news:\u00a0you can display expressions using the DebuggerDisplay attribute!<\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225622\" aria-labelledby=\"figcaption_attachment_225622\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225622 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpression.png\" alt=\"Example of DebuggerDisplay attribute containing an expression\" width=\"1348\" height=\"444\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpression.png 1348w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpression-300x99.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpression-768x253.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpression-1024x337.png 1024w\" sizes=\"(max-width: 1348px) 100vw, 1348px\" \/><figcaption id=\"figcaption_attachment_225622\" class=\"wp-caption-text\"><em>Figure 4 &#8211; Example of DebuggerDisplay attribute containing an expression<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225623\" aria-labelledby=\"figcaption_attachment_225623\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225623 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpressionLocals.png\" alt=\"Locals window with above DebuggerDisplay syntax and added expression evaluation\" width=\"1303\" height=\"513\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpressionLocals.png 1303w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpressionLocals-300x118.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpressionLocals-768x302.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDExpressionLocals-1024x403.png 1024w\" sizes=\"(max-width: 1303px) 100vw, 1303px\" \/><figcaption id=\"figcaption_attachment_225623\" class=\"wp-caption-text\"><em>Figure 5 &#8211; Locals window with above DebuggerDisplay syntax and added expression evaluation<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>Bad news: DebuggerDisplay expressions can cause additional issues when debugging your code. Potential issues include performance hits for large or complex expressions, compilation and runtime errors when the expression&#8217;s language differs from the language being debugged, and application state changes when expressions mutate properties.<\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225624\" aria-labelledby=\"figcaption_attachment_225624\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225624 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDTernaryExpression.png\" alt=\"Figure 6 - DebuggerDisplay attribute with Visual Basic-style ternary expression syntax added\" width=\"1337\" height=\"45\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDTernaryExpression.png 1337w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDTernaryExpression-300x10.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDTernaryExpression-768x26.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/DDTernaryExpression-1024x34.png 1024w\" sizes=\"(max-width: 1337px) 100vw, 1337px\" \/><figcaption id=\"figcaption_attachment_225624\" class=\"wp-caption-text\"><em>Figure 6 &#8211; DebuggerDisplay attribute with Visual Basic-style ternary expression syntax added<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225625\" aria-labelledby=\"figcaption_attachment_225625\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225625 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/ExpressionError.png\" alt=\"Figure 7 - Runtime error received after using above Visual Basic-style syntax while debugging in C#\" width=\"1562\" height=\"477\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/ExpressionError.png 1562w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/ExpressionError-300x92.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/ExpressionError-768x235.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/ExpressionError-1024x313.png 1024w\" sizes=\"(max-width: 1562px) 100vw, 1562px\" \/><figcaption id=\"figcaption_attachment_225625\" class=\"wp-caption-text\"><em>Figure 7 &#8211; Runtime error received after using above Visual Basic-style syntax while debugging in C#<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>But fear not! One way to reduce these potential issues with expressions is by creating a private property or method that returns the string of an executed expression and telling DebuggerDisplay to display that property.<\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225630\" aria-labelledby=\"figcaption_attachment_225630\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225630 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDProperty.png\" alt=\"Figure 8 - Creating a private property containing more complex expressions and formatting referenced by DebuggerDisplay\" width=\"1432\" height=\"352\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDProperty.png 1432w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDProperty-300x74.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDProperty-768x189.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDProperty-1024x252.png 1024w\" sizes=\"(max-width: 1432px) 100vw, 1432px\" \/><figcaption id=\"figcaption_attachment_225630\" class=\"wp-caption-text\"><em>Figure 8 &#8211; Creating a private property containing more complex expressions and formatting referenced by DebuggerDisplay<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225629\" aria-labelledby=\"figcaption_attachment_225629\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225629 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDMethod.png\" alt=\"Figure 9 - Creating a method containing more complex expressions and formatting referenced by DebuggerDisplay\" width=\"1425\" height=\"421\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDMethod.png 1425w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDMethod-300x89.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDMethod-768x227.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/PrivateDDMethod-1024x303.png 1024w\" sizes=\"(max-width: 1425px) 100vw, 1425px\" \/><figcaption id=\"figcaption_attachment_225629\" class=\"wp-caption-text\"><em>Figure 9 &#8211; Creating a method containing more complex expressions and formatting referenced by DebuggerDisplay<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h4>What is the feature equivalent \u00a0to DebuggerDisplay for C++ users?<\/h4>\n<p>DebuggerDisplay is compatible with C#, F#, and Visual Basic, but if you\u2019re debugging in C++, <strong>Natvis<\/strong> is a great alternative!\u00a0 Though not as simple as adding syntax to the top of a class like DebuggerDisplay, adding a .natvis file to a project lets you customize how objects are displayed.<\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225627\" aria-labelledby=\"figcaption_attachment_225627\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225627 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisLocals.png\" alt=\"Figure 10 - Example of Natvis being used in Locals window\" width=\"1301\" height=\"513\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisLocals.png 1301w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisLocals-300x118.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisLocals-768x303.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisLocals-1024x404.png 1024w\" sizes=\"(max-width: 1301px) 100vw, 1301px\" \/><figcaption id=\"figcaption_attachment_225627\" class=\"wp-caption-text\"><em>Figure 10 &#8211; Example of Natvis being used in Locals window<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>Right-click the C++ project node in <strong>Solution Explorer<\/strong>, select <strong>Add <\/strong>&gt; <strong>New Item, <\/strong>and select <strong>Visual C++ &gt; Utility &gt; Debugger visualization file (.natvis)<\/strong>.\u00a0 The result is an XML file where you can control which properties are displayed while debugging.<\/p>\n<p>&nbsp;<\/p>\n<p><figure id=\"attachment_225626\" aria-labelledby=\"figcaption_attachment_225626\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-225626 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisFile.png\" alt=\"Figure 11 - Example Natvis file corresponding to display shown above\" width=\"1437\" height=\"295\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisFile.png 1437w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisFile-300x62.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisFile-768x158.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2019\/06\/NatvisFile-1024x210.png 1024w\" sizes=\"(max-width: 1437px) 100vw, 1437px\" \/><figcaption id=\"figcaption_attachment_225626\" class=\"wp-caption-text\"><em>Figure 11 &#8211; Example Natvis file corresponding to display shown above<\/em><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<p>To learn more about using Natvis while debugging C++ projects, <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/debugger\/create-custom-views-of-native-objects?view=vs-2019\">check out the documentation<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h4>These features are awesome and will save me lots of time!\u00a0 How can I help share DebuggerDisplay and Natvis with others?<\/h4>\n<p>Fun fact: both DebuggerDisplay and Natvis attributes have been in Visual Studio for years!\u00a0 These attributes are extremely useful to most developers but are still not as discoverable and well-known as they could be.\u00a0 As a result, we are currently working to provide an easier method to discover these attributes better, and your feedback will help make this happen!\u00a0 Please <a href=\"https:\/\/www.research.net\/r\/6KCY7WQ\">complete this survey<\/a> which will give us insight in providing an improved experience when using these attributes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Did you know that you can view objects by more than just their types in the Watch, Autos, and Locals windows?  Learn how you can customize your object views in debugger windows using DebuggerDisplay and Natvis!<\/p>\n","protected":false},"author":651,"featured_media":225641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[5,510,9,547,653,12],"class_list":["post-225613","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-csharp","tag-cpp","tag-debug","tag-f","tag-visual-basic","tag-visual-studio"],"acf":[],"blog_post_summary":"<p>Did you know that you can view objects by more than just their types in the Watch, Autos, and Locals windows?  Learn how you can customize your object views in debugger windows using DebuggerDisplay and Natvis!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/225613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/651"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=225613"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/225613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/225641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=225613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=225613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=225613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}