你能在PowerShell中重载函数吗?
我希望我的函数接受字符串,数组或某些开关。
我想要的一个例子:
答案 0 :(得分:26)
在PowerShell中,函数不会重载。最后一个定义会覆盖相同作用域中的上一个定义,或者隐藏父作用域中的上一个定义。因此,您应该创建一个单独的函数,并提供一种通过参数区分其调用模式的方法。
在V2中,您可以使用高级功能,请参阅help about_Functions_Advanced_Parameters
并避免一些手动编码来解决参数集歧义:
# advanced function with 3 parameter sets
function Backup-UsersData
(
[Parameter(Position=0, ParameterSetName="user")]
[string]$user,
[Parameter(Position=0, ParameterSetName="array")]
[object[]]$array,
[Parameter(Position=0, ParameterSetName="all")]
[switch]$all
)
{
# use this to get the parameter set name
$PSCmdlet.ParameterSetName
}
# test
Backup-UsersData -user 'John'
Backup-UsersData 1, 2
Backup-UsersData -all
# OUTPUT:
# user
# array
# all
请注意,这种机制有时很奇怪。例如,在第一个测试中,我们必须明确指定参数名-user
。否则:
Backup-UsersData : Parameter set cannot be resolved using the specified named parameters.
At C:\TEMP\_101015_110059\try2.ps1:21 char:17
+ Backup-UsersData <<<< 'John'
+ CategoryInfo : InvalidArgument: (:) [Backup-UsersData], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Backup-UsersData
在许多情况下,使用混合参数的标准而非高级函数将执行:
function Backup-UsersData
(
[string]$user,
[object[]]$array,
[switch]$all
)
{
if ($user) {'user'}
elseif ($array) {'array'}
elseif ($all) {'all'}
else {'may be'}
}
Backup-UsersData -user 'John'
Backup-UsersData -array 1, 2
Backup-UsersData -all
Backup-UsersData
但在这种情况下,您应该解决(或接受并忽略)歧义,例如:决定如果做什么,比如说:
Backup-UsersData -user 'John' -array 1, 2 -all
答案 1 :(得分:5)
这是罗马答案的变体,我认为它更灵活一些:
function Backup
{
[CmdletBinding(DefaultParameterSetName='Users')]
Param (
[parameter(mandatory=$true, ParameterSetName='Users', position=0, ValueFromPipeline=$true)][string[]]$User,
[parameter(mandatory=$true, ParameterSetName='AllUsers')][switch]$All
)
Begin
{
if ($All) { $User = @('User1', 'User2', 'User3') }
}
Process
{
foreach ($u in $User)
{
echo "Backup $u"
}
}
}
答案 2 :(得分:2)
1)建立一个类...
class c1 {
[int]f1( [string]$x ){ return 1 }
[int]f1( [int ]$x ){ return 2 }
}
1+)如果您希望不带实例化地调用它们,请使用静态方法...
class c1 {
static [int] f1( [string]$x ){ return 1 }
static [int] f1( [int]$x ){ return 2 }
}
2)调用类或对象中的方法...重载可以正常工作
$o1 = [c1]::new()
o1.f1( "abc" ) ~> returns 1
o1.f1( 123 ) ~> returns 2
-OR-
[c1]::f1( "abc" ) ~> returns 1
[c1]::f1( 123 ) ~> returns 2
3)
如果(像我一样)
您想在库中放置“重载函数” ...
这样您的用户就可以透明地使用它们...
从代码或从交互式命令行(REPL)...
我能找到的最接近的
“ Powershell中的重载功能”
是这样的:
function Alert-String() { [c1]::f1( "abc" ) }
function Alert-Strings(){ [c1]::f1( 123 ) }
function Alert-Stringn(){ [c1]::f1( 123 ) }
也许是在PS-Core v8中??? ;-)
希望有帮助...
答案 3 :(得分:1)
如果使用PSObject而不是Object来定义参数类型,则它应该起作用。 例如,函数Get-Control知道如何基于字符串或模板类型进行重载,并且可以使用位置值进行调用:
Get-Control "A-Name-Of-A-Control"
Get-Control $template
要使超载正常工作,请按以下方式使用PSObject:
Function Get-Control {
Param(
[Parameter(Mandatory=$False,ParameterSetName="ByTemplate",Position=0)]
[PSObject]
$Template,
[Parameter(Mandatory=$False,ParameterSetName="ByName",Position=0)]
[String]
$Name,
[Parameter(Mandatory=$False)]
[Switch]
$List
)
... # remaining code removed for brevity