PowerShell
PowerShell copied to clipboard
Improve `OrderedHashtable` integration
Summary of the new feature / enhancement
The new System.Management.Automation.OrderedHashtable
class is a great step forward in moving to a dictionary that is ordered by default. Therefore I wouldn't be surprised that this System.Management.Automation.OrderedHashtable
class would eventually replace the System.Collections.Specialized.OrderedDictionary
class.
For this to happen, I would like to able to use the same syntactic sugars as with the Hashtable
/Ordered
type:
-
Preserve the hash literal node order
Currently this doesn't work as expected (like it does for
[PSCustomObject]
and[Ordered]
):
[System.Management.Automation.OrderedHashtable]@{ One = 1; Two = 2; Three = 3; Four = 4 }
Name Value
---- -----
Two 2
Four 4
One 1
Three 3
Side note: unlike the OrderedDictionary
class, I think it is ok that the OrderedDictionary
is able to cast from an unordered (non-literal) hash table (assuming that it will be documented that the order is already decayed in this matter):
$Hashtable = @{ One = 1; Two = 2; Three = 3; Four = 4 }
[System.Management.Automation.OrderedHashtable]$HashTable
-
Ability to use the friendly name to cast
As with the
[Ordered]
(and[HashTable]
) type, I would like to be able to use it friendly name:
[OrderedHashtable]@{ One = 1; Two = 2; Three = 3; Four = 4 }
-
ability to compare with its friendly name
As with the
[Ordered]
type (see: #10513), I would like to be able to use its friendly name for the-is
comparison:
$OrderedHashtable = [System.Management.Automation.OrderedHashtable]@{ One = 1; Two = 2; Three = 3; Four = 4 }
$OrderedHashtable -is [OrderedHashtable]
- Also, I would expect it somehow (pretend) to be derived from the
OrderedDictionary
class Currently the following returnsFalse
, where I would like to see itTrue
so that doesn't break scripts that test for anOrderedDictionary
type:
$OrderedHashtable = [System.Management.Automation.OrderedHashtable]@{ One = 1; Two = 2; Three = 3; Four = 4 }
$OrderedHashtable -is [Ordered]
False # Expected (wishful thinking) True
Related: #19073
The issue you link to:
- https://github.com/PowerShell/PowerShell/issues/19073
would give you most of what you want implicitly, so do you have specific concerns about that proposal that would call for what you're proposing here instead?
If #19073 is implemented, you'd simply get ordered hashtables by default.
A [OrderedHashtable]
type accelerator would then only be needed for -is [OrderedHashtable]
or - hypothetically for now, because no such constructor overload exists - for creating case-sensitive hash tables, e.g. [OrderedHashtable]::new([System.StringComparer]::InvariantCulture)
).
I would expect it somehow (pretend) to be derived from the OrderedDictionary class
I don't think such a "white lie" is a good idea, as it can create confusion, and there may be cases where you do want to distinguish [ordered]
from [OrderedHashtable]
.
If you really need to know whether a preexisting instance maintains definition order, which doesn't strike me as a common use case,$ht -is [ordered] -or $ht -is [OrderedHashtable]
isn't too much of a hardship.
Therefore I wouldn't be surprised that this
System.Management.Automation.OrderedHashtable
class would eventually replace theSystem.Collections.Specialized.OrderedDictionary
class.
#19073 would allow for that, with the only change of habit required from users is to apply the positional indexing to the .Values
property instead of directly to the hashtable. ($oht = @{ foo = 'one'; bar = 'two' }; $oht.Values[1]
(doesn't currently work) instead of $oht = [ordered] @{ foo = 'one'; bar = 'two' }; $oht[1]
(in v7.3+, .Values[1]
works with [ordered]
too, thanks to your own efforts.)
Cross-edition code will be stuck with [ordered]
.
[ordered]
is a type accelerator to OrderedDictionary
so changing that would be a big breaking change. We could certainly add a type accelerator for [orderedhashtable]
which wouldn't be a breaking change, but the implicit idea from @mklement0 is probably a better choice that would resolve many of these issues if accepted.
As much as I still love the idea of making hashtable literals uses OrderedDictionary
by default, running some benchmarks has convinced me that this isn't feasible due to backward compatibility concerns, after all: programmatic construction of (larger) OrderedDictionary
instances is substantially slower than with [hashtable]
(and also uses more memory).
- see https://github.com/PowerShell/PowerShell/issues/19073#issuecomment-1476750522.
I have therefore closed #19073.
Please triage this issue and either mark it with something like Resolution-Declined or put it on a kind of wishlist "Issue we would like to prioritize, but we can't commit we will get to it yet"