Passing an ordered hashtable to a function

How can I pass an ordered hash table to a function?

Next, the error message "An ordered attribute can only be specified in the node hash literal" is displayed.

function doStuff { Param ( [ordered]$theOrderedHashtable ) $theOrderedHashtable } $datFileWithMinSizes = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847" } doStuff -theOrderedHashtable $datFileWithMinSizes 

The correct order is not supported:

 function doStuff { Param ( [Hashtable]$theOrderedHashtable = [ordered]@{} ) $theOrderedHashtable } $datFileWithMinSizes = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847" } doStuff -theOrderedHashtable $datFileWithMinSizes 

The only way I can work now is not to specify the type as follows, but I want to specify the type:

 function doStuff { Param ( $theOrderedHashtable ) $theOrderedHashtable } $datFileWithMinSizes = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847" } doStuff -theOrderedHashtable $datFileWithMinSizes 
+5
source share
3 answers

Use the full type name:

 function Do-Stuff { param( [System.Collections.Specialized.OrderedDictionary]$OrderedHashtable ) $OrderedHashtable } 

To support both regular hash tables and ordered dictionaries, you will have to use separate sets of parameters: use the [System.Collections.IDictionary] interface, as suggested by the British

 function Do-Stuff { [CmdletBinding(DefaultParameterSetName='Ordered')] param( [Parameter(Mandatory=$true,Position=0,ParameterSetName='Ordered')] [System.Collections.Specialized.OrderedDictionary]$OrderedHashtable, [Parameter(Mandatory=$true,Position=0,ParameterSetName='Hashtable')] [hashtable]$Hashtable ) if($PSCmdlet.ParameterSetName -eq 'Hashtable'){ $OrderedHashtable = $Hashtable } $OrderedHashtable } 
+5
source

Matthias is right, but I would like to point out that there is a way to accept both types without using parameter sets.

Both types implement the IDictionary interface, so you can strictly enter your parameter using the interface, and then any type will be accepted (including custom types that you create or don't know yet) that implement the interface

 function Do-Stuff { [CmdletBinding(DefaultParameterSetName='Ordered')] param( [Parameter(Mandatory=$true,Position=0,ParameterSetName='Ordered')] [System.Collections.IDictionary]$Dictionary ) $Dictionary.GetType().FullName } 

This will take both:

 C:\WINDOWS\system32\WindowsPowerShell\v1.0> do-stuff @{} System.Collections.Hashtable C:\WINDOWS\system32\WindowsPowerShell\v1.0> do-stuff ([ordered]@{}) System.Collections.Specialized.OrderedDictionary 

Similarly, if you want to accept only an ordered dictionary (but not just a specific type of OrderedDictionary ), you can use the IOrderedDictionary interface, which is implemented by the aforementioned type, but not [hashtable] :

 function Do-Stuff { [CmdletBinding(DefaultParameterSetName='Ordered')] param( [Parameter(Mandatory=$true,Position=0,ParameterSetName='Ordered')] [System.Collections.Specialized.IOrderedDictionary]$Dictionary ) $Dictionary.GetType().FullName } 

Then:

 C:\WINDOWS\system32\WindowsPowerShell\v1.0> do-stuff ([ordered]@{}) System.Collections.Specialized.OrderedDictionary C:\WINDOWS\system32\WindowsPowerShell\v1.0> do-stuff @{} Do-Stuff : Cannot process argument transformation on parameter 'Dictionary'. Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Collections.Specialized.IOrderedDictionary". At line:1 char:10 + do-stuff @{} + ~~~ + CategoryInfo : InvalidData: (:) [Do-Stuff], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Do-Stuff 
+5
source

Just to complement existing helpful answers :

What is the error message

An ordered attribute can only be specified in a hash literal node.

trying to tell you:

[ordered] placed in front of the hash table literal is just syntactic sugar, and it only works until hashtable characters ( @{ ... } ).

You can determine the actual type of the ordered hash table literal as follows:

 > ([ordered] @{ foo = 1 }).GetType().FullName System.Collections.Specialized.OrderedDictionary 

That is, the ordered hash table literal in PowerShell is an instance of the type [System.Collections.Specialized.OrderedDictionary] .

+3
source

Source: https://habr.com/ru/post/1264966/


All Articles