PowerShell 函数可以处理多种输入类型吗?
Can a PowerShell function handle multiple input types?
我正在开发一个比较两个对象的函数,以便检测它们是否相同。但是我希望它也能与其他类型一起使用,例如字符串或整数。
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
并分配了适当的类型)
正如 Jeff Zeitlin 在他的评论中所说:
用户不必明确指定参数集 - PowerShell 从参数的特定组合(或没有)在调用时传递。
根据参数数据类型推断,参数是否位置传递(不在参数名称前面)以及哪些参数被标记为mandatory,并且生效的参数集名称反映在(advanced) script / function调用的$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."
}
}
但是,如果使用 相同的参数名称 不是必需的,并且您满足于 positional使用不同数据类型的调用、参数集可以提供帮助,如下面的简化示例所示:
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 $_ }
上面的结果如下,表明参数数据类型自动选择了合适的参数集:
Parameter set chosen: int
Parameter set chosen: hash
我正在开发一个比较两个对象的函数,以便检测它们是否相同。但是我希望它也能与其他类型一起使用,例如字符串或整数。
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
并分配了适当的类型)
正如 Jeff Zeitlin 在他的评论中所说:
用户不必明确指定参数集 - PowerShell 从参数的特定组合(或没有)在调用时传递。
根据参数数据类型推断,参数是否位置传递(不在参数名称前面)以及哪些参数被标记为mandatory,并且生效的参数集名称反映在(advanced) script / function调用的$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."
}
}
但是,如果使用 相同的参数名称 不是必需的,并且您满足于 positional使用不同数据类型的调用、参数集可以提供帮助,如下面的简化示例所示:
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 $_ }
上面的结果如下,表明参数数据类型自动选择了合适的参数集:
Parameter set chosen: int
Parameter set chosen: hash