# create ordered dictionary via [ordered] syntactic sugar
$a = [ordered]@{}
$a['Larry'] = 'Poik!'
$a['Curly'] = 'Nyuk!'
$a['Moe'] = 'Wise guy!'
# get 2nd item from ordered hash
$a[1]
# returns: Nyuk!
# Persist to disk
$a | Export-Clixml ./tempObject.xml
# Deserialize
$b = Import-Clixml ./tempObject.xml
# get 2nd item from rehydrated ordered hash
$b[1]
# returns: Nyuk!
# returns: $null
$a | Get-Member
TypeName: System.Collections.Specialized.OrderedDictionary
...
$b | Get-Member
TypeName: Deserialized.System.Collections.Specialized.OrderedDictionary
...
Deserialized object does not have the full implementation of the original OrderedDictionary object.
> $PSVersionTable
Name Value
---- -----
SerializationVersion 1.1.0.1
PSEdition Core
BuildVersion 3.0.0.0
PSRemotingProtocolVersion 2.3
WSManStackVersion 3.0
PSVersion 6.0.0-alpha
GitCommitId v6.0.0-alpha.13-42-gf38d09dc6d7bf208cd78d86e1...
CLRVersion
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
@HipCzeck Could you make the test with the latest build Powershell 6.0?
I've tested in the latest nightly build 6.0.0.13 alpha.
The output is the same in the actual behaviour section above, and the Environment Data section has been updated to indicate version used.
@HipCzeck Thanks for the issue report!
Feel free to use Powershell 6 everyday, make suggestions and report new issues.
The issue still exists in PowerShell Core v6.0.0-beta.4.
What Get-Member
reports is not the true type name; it is merely the first type name as reported by .pstypename
, as part of PowerShell's ETS (extended type system), which typically, but not necessarily, reflects the actual .NET type - and doesn't, in this case.
$b.GetType().FullName
reveals that what was actually deserialized was a _regular_ hashtable, with _unordered_ keys (verify with $b.Keys
), which also explains the inability to index.
The deserializer currently blindly - and incorrectly - assumes that a type that implements IDictionary
must be a [System.Collections.Hashtable]
instance, and therefore incorrectly "rehydrates" [System.Collections.Specialized.OrderedDictionary]
instances as regular [System.Collections.Hashtable]
instances.
@iSazonov: Please label this as a bug.
@mklement0 Thanks for investigating this! It seems looks as Enhancement.
@PaulHigin Could you please comment the Issue?
@iSazonov:
While I understand that not all objects can be faithfully recreated during deserialization, this is a case where it can be done (at least with the respect to the container (collection) itself) and _should_ be done, because not doing so can lead to subtle bugs.
My _guess_ is that the serialization code was written pre-v3, when only regular hashtables were supported in PowerShell, and when ordered ones were introduced in v3, the serialization code wasn't updated accordingly.
I guess that if we make full review we discover another samples. We haven't full test set for serialization. We discussed an idea for remoting that we can do serialization-deserialization test for all types in PowerShell Core by connect to localhost and do the same for a fixed set from Windows PowerShell.
This certainly looks like a gap in the serialization, however, since this is an existing gap, it is an enhancement
and something we can address in the future.
Related #3172.
Related: Deserialized ordered dictionaries do not maintain the key order.
It looks like serialization wasn't updated to handle [ordered] after it was introduced. As @SteveL-MSFT mentions, this can be added at any time.
Most helpful comment
This certainly looks like a gap in the serialization, however, since this is an existing gap, it is an
enhancement
and something we can address in the future.