【问题标题】:Passing an ordered hashtable to a function将有序哈希表传递给函数
【发布时间】:2017-07-22 23:27:28
【问题描述】:

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

以下抛出错误:

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

【问题讨论】:

    标签: powershell powershell-3.0


    【解决方案1】:

    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类型),你可以使用IOrderedDictionary接口,它由上述类型实现,但不是由[hashtable]

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

    然后:

    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
    

    【讨论】:

      【解决方案2】:

      使用完整的类型名称:

      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
      }
      

      【讨论】:

        【解决方案3】:

        只是补充现有的有用答案

        什么错误信息

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

        想告诉你:

        [ordered]语法糖,它只在哈希表literals (@{ ... }) 之前有效。

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

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

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

        【讨论】:

        • 这很有帮助。我之前也尝试过 [OrderedDictionary],它是从 ([ordered] @{ foo = 1 }).GetType().Name 检索到的,但这不起作用。 ([ordered] @{ foo = 1 }).GetType().FullName 获取完整的类型名称,这确实有效。
        猜你喜欢
        • 1970-01-01
        • 2012-10-07
        • 2020-06-14
        • 1970-01-01
        • 2013-09-04
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        相关资源
        最近更新 更多