Function Powershell函数能否处理多种输入类型?

Function Powershell函数能否处理多种输入类型?,function,powershell,parameter-sets,Function,Powershell,Parameter Sets,我正在研究一个比较两个对象的函数,以便检测它们是否相同。不过,我希望它也能处理其他类型,如字符串或整数 C++允许您使用相同的名称声明不同的函数,以不同的方式处理具有不同输入类型的函数调用。我知道参数集的存在,但据我所知,用户必须指定他使用的参数集 我正试着做这样的事情 function Compare-Objects{ Param( [Parameter(Mandatory=$true, Position=0, ParameterSetN

我正在研究一个比较两个对象的函数,以便检测它们是否相同。不过,我希望它也能处理其他类型,如字符串或整数

C++允许您使用相同的名称声明不同的函数,以不同的方式处理具有不同输入类型的函数调用。我知道参数集的存在,但据我所知,用户必须指定他使用的参数集

我正试着做这样的事情

function Compare-Objects{
    Param(
        [Parameter(Mandatory=$true,
        Position=0,
        ParameterSetName = "Hashtables")]
        [ValidateNotNullOrEmpty()] 
        [Hashtable]$Item1Hash,

        [Parameter(Mandatory=$true,
        Position=0,
        ParameterSetName = "Integers")]
        [ValidateNotNullOrEmpty()] 
        [int]$Item1int,

        [Parameter(Mandatory=$true,
        Position=1,
        ParameterSetName = "Hashtables")]
        [ValidateNotNullOrEmpty()]
        [Hashtable]$Item2Hash,

        [Parameter(Mandatory=$true,
        Position=1,
        ParameterSetName = "Integers")]
        [ValidateNotNullOrEmpty()]
        [Hashtable]$Item2Int
    )
    if($PSCmdlet.ParameterSetNamePositionv -match "Integers"){ Return ($Item1Int -eq $Item2Int)}
    else{
    #do some other stuff with $Item1Hash and $Item2Hash
    }
}
如果我还可以将变量命名为相同的变量(因此
$Item1Hash
$Item1Int
都成为
$Item1
,并分配适当的类型)

如他的评论中所述:

用户不必显式指定参数集-PowerShell根据调用时传递的特定参数组合(或没有参数组合)推断适用的参数集

推理基于参数数据类型、参数是否按位置传递(不在参数名称之前)、哪些参数被标记为强制参数,以及生效的参数集名称反映在调用的参数集中的
$PSCmdlet.ParameterSetName

这种推断适用参数集的能力类似于类C语言中的自动重载解析


虽然任何给定的参数都可以参与多个参数集,并且在默认情况下是所有参数集的一部分,但从根本上讲,您不能使用相同的名称但不同的数据类型声明参数

如果需要此类“多态”参数,则必须实现自己的逻辑,而不依赖于参数集:

function Compare-Objects {

  [CmdletBinding(PositionalBinding=$false)]
  Param(

      [Parameter(Mandatory, Position=0)]
      [ValidateNotNullOrEmpty()] 
      # Define as [object] to initially accept any value; specific types
      # are later enforced inside the function body.
      [object] $Item1 
      ,
      [Parameter(Mandatory, Position=1)]
      [ValidateNotNullOrEmpty()] 
      [object] $Item2
  )

  # Ensure that a supported type was passed.
  if ($Item1.GetType() -notin [int], [hashtable]) { Throw "Unsupported argument type." }

  # Ensure that both arguments have the same type.
  if ($Item1.GetType() -ne $Item2.GetType()) { Throw "Inconsistent argument types." }

  if ($Item1 -is [int]) {
    "[int] arguments given."
  }
  else {
    "[hashtable] arguments given."
  }

}

但是,如果不要求使用相同的参数名,并且您满足于使用不同的数据类型进行位置调用,则参数集可以提供帮助,如下简化示例所示:

function Foo {
  [CmdletBinding()]
  param(
    [Parameter(ParameterSetName='int', Position=0)]
    [int] $ItemInt
    ,
    [Parameter(ParameterSetName='hash', Position=0)]
    [hashtable] $ItemHash
  )
  "Parameter set chosen: $($PSCmdlet.ParameterSetName)"
 } 

# Call the function first with an [int], then with a [hashtable], positionally.
10, @{ foo = 1 } | ForEach-Object { Foo $_ }
上述结果表明,参数数据类型自动选择了适当的参数集:

选择的参数集:int 选择的参数集:哈希
在PowerShell中使用参数集时,必须至少有一个唯一的参数或参数组合;这就是PowerShell知道您正在调用哪个参数集的方式。(唯一性是通过组合参数类型和“强制”状态等属性来定义的。)作为用户,您不必告诉PowerShell要显式使用哪个集合;它的处理方式就像在C族语言中调用重载函数一样——事实上,有人会认为PowerShell参数集实际上是重载的一种原始形式。