将有序哈希表传递给函数

时间:2017-03-03 01:17:38

标签: powershell powershell-v3.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

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

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

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

doStuff -theOrderedHashtable $datFileWithMinSizes

我目前唯一能让它工作的方法是不按如下方式指定类型,但我想指定类型:

function doStuff {
    Param (
        $theOrderedHashtable
    )
    $theOrderedHashtable
}

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

doStuff -theOrderedHashtable $datFileWithMinSizes

3 个答案:

答案 0 :(得分:7)

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

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

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

这将同时接受:

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

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

同样,如果你想只接受一个有序词典(但不是特定的OrderedDictionary类型),你可以使用{{1} } interface,由前面提到的类型实现,但不是由IOrderedDictionary实现:

[hashtable]

然后:

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

    )

    $Dictionary.GetType().FullName
}

答案 1 :(得分:5)

使用完整类型名称:

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

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

答案 2 :(得分:3)

补充现有的有用答案

错误消息

  

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

试图告诉你:

放置在哈希表文字之前的

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

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

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

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