Simplified Debug Visualizers for all my TNullableTypes

After playing around with debug visualizers, I found that there is a very simple way to provide a visualiser for many record types: Just add a special method (I called it Dump) to those records that returns a string that you can then evaluate in the debugger and display in the debug windows.
There are two caveats though:

  1. Calling a method from a debug visualiser is slow. If there are multiple types, e.g. in the Local Variables debug window, there is a noticeable delay every time that window is refreshed. At least on my computer.
  2. You need to make sure that the Dump method is not removed by the linker.

For the latter there is a simple trick:

unit u_dzNullableDateTime;

interface

type
  TNullableDateTime = record
  private
    FIsValid: INullableTypesFlagInterface;
    FValue: TDateTime;
  public
    function Dump: string;
    // other methods and operators
  end;

// ...
implementation
// ...

function TNullableDateTime.Dump: string;
begin
  if IsValid then
    Result := DateTimeToStr(Value)
  else
    Result := '<invalid>';
end;

{$IFDEF DEBUG}
procedure AssertDumpAvailable;
var
  dt: TNullableDateTime;
begin
  dt.Dump;
end;

initialization
  AssertDumpAvailable;
{$ENDIF DEBUG}
end.

This way the Dump method is called from the initialization section and is not removed by the linker. Wrapping this code in {$IFDEF DEBUG} ensures, that this only happens when compiling for debugging.

Unfortunately there isn’t much that can be done about the slowdown of the debugging display. It is caused by the evaluator calling the Dump method in the debugged executable, waiting for the function to return and then passing the result back to the debug visualizer. The only way to avoid this would be to move the code from the Dump method into the debug visualizer. I tried this first but it turned out to be a lot of work, as the visualizer needs to know exactly how to interpret the record fields, read them and then convert them into a suitable format. Yes, that’s the whole point of a debug visualizer, of course, but being a lazy basterd™ I don’t really want to write that much code for basically no gain.

Building on the above, it is possible to write a generalized debug visualizer which can be user-configured to register itself for any data type and pass a user-configurable expression to the debugger for evaluation. I might extend dzDebugVisualizer to provide this functionality at a later time.

Discussion about this post in the international Delphi Praxis forum.