Powershell 中的函数指针

问题描述 投票:0回答:3

考虑以下功能

Function IfFunctionExistsExecute
{
    param ([parameter(Mandatory=$true)][string]$func)
    begin 
    {
        # ...
    }
    process
    {
        if(Get-Command $func -ea SilentlyContinue)
        {
            & $func # the amperersand invokes the function instead of just printing the variable
        }
        else
        {
            # ignore
        }       
    }
    end
    {
        # ...
    }
}

用法:

Function Foo { "In Foo" }
IfFunctionExistsExecute Foo

这行得通。

但是这不起作用:

Function Foo($someParam) 
{ 
     "In Foo"
     $someParam
}

IfFunctionExistsExecute Foo "beer"

然而这给了我丑陋的错误:

IfFunctionExistsExecute : A positional parameter cannot be found that accepts argument 'beer'.
At C:\PSTests\Test.ps1:11 char:24
+ IfFunctionExistsExecute <<<<  Foo "beer"
    + CategoryInfo          : InvalidArgument: (:) [IfFunctionExistsExecute], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,IfFunctionExistsExecute

如何在 PS 中执行此操作?

function powershell function-pointers
3个回答
2
投票

尝试在调用的函数和

IfFunctionExistsExecute
函数上创建一个可选参数;像这样:

Function IfFunctionExistsExecute
{
    param ([parameter(Mandatory=$true)][string]$func, [string]$myArgs)
        if(Get-Command $func -ea SilentlyContinue)
        {
            & $func $myArgs  # the amperersand invokes the function instead of just printing the variable
        }
        else
        {
            # ignore
        }       
}

Function Foo
{ 
    param ([parameter(Mandatory=$false)][string]$someParam)
    "In Foo" 
    $someParam
}

IfFunctionExistsExecute Foo
IfFunctionExistsExecute Foo "beer"

对我来说:

C:\test>powershell .\test.ps1
In Foo

In Foo
beer

C:\test>

1
投票

也许您也应该将参数传递给被调用函数:

$arguments = $args[1..($args.Length-1)]
& $func @arguments

0
投票

我写了我的解决方案。以 powershell 风格命名的函数:Verb-Noun。它支持命名参数和剩余参数。

function Invoke-FunctionIfExist {
    [CmdletBinding()]
    param (
        # Function name
        [Parameter(Mandatory, Position=0)]
        [string]
        $Name,
        # Hashtable with named arguments
        [Parameter()]
        [hashtable]
        $Parameters = @{},
        # Rest of arguments
        [Parameter(ValueFromRemainingArguments)]
        [object[]]
        $Arguments = @()
    )

    process {
        if (Get-Command $Name -ErrorAction SilentlyContinue) {
            & $Name @NamedArguments @Arguments
        }
    }
}

用法示例:

PS> Invoke-FunctionIfExist Foo
In Foo
PS> Invoke-FunctionIfExist Foo beer
In Foo
beer
PS> Invoke-FunctionIfExist Foo -Parameters @{someParam='beer'}
In Foo
beer
© www.soinside.com 2019 - 2024. All rights reserved.