partial PR15118 backport
Backport note: something similar in spirit was done in D1655, but
conflicts with how Core ended up doing it. This overrides that change
and syncs to how Core does it currently. The class itself is unchanged
except for the ToString method being moved to cpp file.
Depends on D3586