Is it possible to reference another property in a

2019-08-24 11:01发布

问题:

Background

It started with a cmdlet as an answer for Save hash table in PowerShell object notation (PSON). Meanwhile evolved to ConvertTo-Expression. A cmdlet that serializes PowerShell objects to a PowerShell expression.
Being a little involved in the -Depth issues with similar native cmdlets (ConvertTo-Xml and ConvertTo-Json) due to recurring property references, I am wondering if this issue could be nicely resolved in a PowerShell expression.

Example

$Object = @{
    Name = "Parent"
    Child = @{
        Name = "Child"
    }
}
$Object.Child.Parent = $Object

In this example, the .Child.Parent property refers back to $Object, meaning $Object.Child.Parent.Child.Parent.Name returns Parent.
Currently, the $Object | ConvertTo-Expression returns a ScriptBlock like:

 @{
        'Child' = @{
                'Parent' = $_
                'Name' = 'Parent'
        }
        'Name' = 'Parent'
}

To reconstruct the (recurring) property reference, I might return an expression like this:

[ScriptBlock]::Create(
@'
$_ = @{
        'Child' = @{
                'Parent' = $_
                'Name' = 'Parent'
        }
        'Name' = 'Parent'
}
$_.Child.Parent = $_
$_
'@
)

(Similar to how the object is initially constructed in the example.)
Restoring (invoking, deserializing) , this expression, takes something like:

$Expression = [ScriptBlock]::Create(... # The above result
$Object = &$Expression
$Object.Child.Parent.Name

But such an output would very much muddle the result for readability.

Question

Are there any other ways (e.g. using $This, a ScriptProperty or ...) to restore a referenced property in a PowerShell object?
Is it possible to reference another property at construction time?
(I understand that the object itself is not complete, but the parent reference presumably already exists. Besides, I could imaging that the reference doesn't need to exists yet by doing some like a lazy initialization.)