Powershell: Deserialized Ordered Dictionary via Import-Clixml is not numerically indexable.

Created on 8 Dec 2016  路  11Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

# 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]

Expected behavior

# returns: Nyuk!

Actual behavior

# 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.

Environment data

> $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...}
Area-Cmdlets Issue-Enhancement Up-for-Grabs

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.

All 11 comments

@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.

See here and here.

@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.

Was this page helpful?
0 / 5 - 0 ratings