将有序哈希表传递给函数

Opo*_*oni 7 powershell powershell-3.0

如何将有序哈希表传递给函数?

以下引发错误:

可以仅在散列文字节点上指定ordered属性.

function doStuff {
    Param (
        [ordered]$theOrderedHashtable
    )
    $theOrderedHashtable
}

$datFileWithMinSizes  = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847"  }

doStuff -theOrderedHashtable $datFileWithMinSizes
Run Code Online (Sandbox Code Playgroud)

以下内容未保持正确的顺序:

function doStuff {
    Param (
        [Hashtable]$theOrderedHashtable = [ordered]@{}
    )
    $theOrderedHashtable
}

$datFileWithMinSizes  = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847"  }

doStuff -theOrderedHashtable $datFileWithMinSizes
Run Code Online (Sandbox Code Playgroud)

我目前能够使用它的唯一方法是不指定类型如下,但我想指定类型:

function doStuff {
    Param (
        $theOrderedHashtable
    )
    $theOrderedHashtable
}

$datFileWithMinSizes  = [ordered]@{"FileA.DAT" = "4"; "FileB.DAT" = "5"; "FileC.DAT" = "91" ; "FileD.DAT" = "847"  }

doStuff -theOrderedHashtable $datFileWithMinSizes
Run Code Online (Sandbox Code Playgroud)

bri*_*ist 10

Mathias是对的,但我想指出有一种方法可以在不使用参数集的情况下接受这两种类型.

这两种类型都实现了IDictionary接口,因此您可以使用接口强类型化参数,然后接受实现接口的任何类型(包括您创建或不知道的自定义类型):

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

这将同时接受:

C:\WINDOWS\system32\WindowsPowerShell\v1.0> do-stuff @{}
System.Collections.Hashtable

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

同样,如果您只想接受有序字典(但不仅仅是特定OrderedDictionary类型),您可以使用IOrderedDictionary由上述类型实现的接口,但不能使用[hashtable]:

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

    )

    $Dictionary.GetType().FullName
}
Run Code Online (Sandbox Code Playgroud)

然后:

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
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 6

只是为了补充现有的、有用的答案

错误信息是什么

只能在散列文字节点上指定有序属性。

试图告诉你:

[ordered]语法糖,它只在哈希表文字( @{ ... }) 之前起作用。

您可以按如下方式确定有序哈希表文字的实际类型:

PS> ([ordered] @{ foo = 1 }).GetType().FullName
System.Collections.Specialized.OrderedDictionary
Run Code Online (Sandbox Code Playgroud)

也就是说,PowerShell 中的有序哈希表文字是 类型的实例[System.Collections.Specialized.OrderedDictionary]

  • 这非常有帮助。我之前也尝试过 [OrderedDictionary],它是从 ([ordered] @{ foo = 1 }).GetType().Name 检索的,但这不起作用。([ordered] @{ foo = 1 }).GetType().FullName 获取有效的完整类型名称。 (3认同)

Mat*_*sen 5

使用完整类型名称:

function Do-Stuff {
    param(
        [System.Collections.Specialized.OrderedDictionary]$OrderedHashtable
    )
    $OrderedHashtable
}
Run Code Online (Sandbox Code Playgroud)

要支持常规哈希表和有序词典,您必须使用单独的参数集:使用[System.Collections.IDictionary]界面,如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
}
Run Code Online (Sandbox Code Playgroud)