Passing an ordered hashtable to a function
Mathias is right, but I wanted 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 strongly type your parameter with the interface instead, and then any type (including custom types that you create or don't know about yet) which implements the interface will be accepted:
function Do-Stuff {
[CmdletBinding(DefaultParameterSetName='Ordered')]
param(
[Parameter(Mandatory=$true,Position=0,ParameterSetName='Ordered')]
[System.Collections.IDictionary]$Dictionary
)
$Dictionary.GetType().FullName
}
This would accept 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 only accept an ordered dictionary (but not just the specific OrderedDictionary
type), you can use the IOrderedDictionary
interface, which is implemented by the aforementioned type, but not by [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
Use the full type name:
function Do-Stuff {
param(
[System.Collections.Specialized.OrderedDictionary]$OrderedHashtable
)
$OrderedHashtable
}
To support both regular hashtables and ordered dictionaries, you'll have to use separate parameter sets: use the [System.Collections.IDictionary]
interface, as suggested by briantist
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
}