Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio Natvis DisplayString Conditionals

Using Visual Studio 2017, I'm writing a Visualizer for some classes, but I'm running into issues with respect to the .natvis code readability. I have a custom Array type, and I would like to display its members in the Watch window's Value field directly (as opposed to having to use the expand button).

arrayType is an enum defining the array type (Sparse, Empty, Dense, Singleton). numElems is the number of entries in the array. No need to focus on this data structure; it's just an example. Here is my current natvis code:

<Type Name="MyProject::MyArray"
  <DisplayString Condition="numElems == 0">
    {arrayType,  en}
  </DisplayString>
  <DisplayString Condition="numElems == 1">
    {arrayType,  en} {*elems[0]}
  </DisplayString>
  <DisplayString Condition="numElems == 2">
    {arrayType,  en} {*elems[0]}, {*elems[1]}
  </DisplayString>
  <DisplayString Condition="numElems == 3">
    {arrayType,  en} {*elems[0]}, {*elems[1]}, {*elems[2]}
  </DisplayString>
  <DisplayString Condition="numElems >= 4">
    {arrayType,  en} {*elems[0]}, {*elems[1]}, {*elems[2]}, ...
  </DisplayString>
</Type>

[Notice that I have to repeat the same code over again (just adding an extra element to display). I'm stopping at displaying 3 elements due to the code bloat.]

This would allow the Watch Window (within Visual Studio) to display objects in the following manner:

Name       Value
arr1       Sparse 5, 3                         ; numElems is 2
arr2       Empty                               ; numElems is 0
arr3       Singleton 1                         ; numElems is 1
arr4       Dense 58, 23, 1, ...                ; numElems is >= 4

Ideally, the DisplayString tag would allow conditionals within it. I've tried the following workaround with C++ ternary operators, which did not work.

<Type Name="MyProject::Array"
  <DisplayString>
    {arrayType,  en} {(numElems >= 1) ? *elems[0] : ""}, {(numElems >= 2) ? *elems[1] : ""}, {(numElems >= 3) ? *elems[2] : ""}, {(numElems >= 4) ? "..." : ""}
  </DisplayString>
</Type>

Notice that in this code, I don't have to repeat the DisplayString tag multiple times over and duplicate code. Maybe there is a way to provide an iterator within the DisplayString so as to list all the (variable amount of) elements? I know about the ArrayItems tag, but that must be used within an Expand tag (again, I'm trying to display the array elements in the Value field (without having to click the expand button)).

Any suggestions? Need clarification? Thanks!

like image 944
xfern Avatar asked Nov 06 '17 01:11

xfern


2 Answers

It is not possible. What you already have is the only way to implement what you want (multiple DisplayStrings with conditionals).

like image 66
Jack Zhai-MSFT Avatar answered Sep 19 '22 15:09

Jack Zhai-MSFT


You can also use {elems,[numElems]}, which is simple but displays also the pointer.

like image 30
user10132334 Avatar answered Sep 19 '22 15:09

user10132334