2010-05-11 64 views
8

通用规范缺省值不在PsBoundParameters中的参数?

考虑以下代码:

PS> function Test { param($p='default value') $PsBoundParameters } 
PS> Test 'some value' 
Key                Value 
---                ----- 
p                 some value 
PS> Test 
# nothing 

我预计$PsBoundParameters将含有记录在这两种情况下$p变量。这是正确的行为吗?

问题

我想用泼洒,将工作像这样的很多功能:

function SomeFuncWithManyRequiredParams { 
    param(
    [Parameter(Mandatory=$true)][string]$p1, 
    [Parameter(Mandatory=$true)][string]$p2, 
    [Parameter(Mandatory=$true)][string]$p3, 
    ...other parameters 
) 
    ... 
} 
function SimplifiedFuncWithDefaultValues { 
    param(
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
    ...other parameters 
) 
    SomeFuncWithManyRequiredParams @PsBoundParameters 
} 

我不想叫SomeFuncWithManyRequiredParams与所列举的所有PARAMS:

SomeFuncWithManyRequiredParams -p1 $p1 -p2 $p2 -p3 $p3 ... 

这可能吗?

+0

有两个问题我不得不问在这里,每个参数的问题:为什么SomeFunc不具有与SimplifiedFunc相同的默认值?而且,如果默认值需要不同,那么为什么SimplifiedFunc允许用户覆盖默认值(因为在这种情况下,他们可以直接调用SomeFunc来覆盖)? – jpaugh 2017-02-01 15:55:36

回答

5

这取决于你如何定义“绑定”我猜即是从用户提供的值或由函数提供的默认值的值?老实说,它并没有让我感到惊讶,它表现了它的行为方式,因为我认为“绑定”是指用户输入的前者。

function SimplifiedFuncWithDefaultValues { 
    param( 
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
    ...other parameters 
) 
    if (!$PSBoundParameters.ContainsKey(p1)) 
    { 
    $PSBoundParameters.p1 = 'default for p1' 
    } 
    # rinse and repeat for other default parameters. 
    SomeFuncWithManyRequiredParams @PSBoundParameters 
} 
+0

好吧,我同意'$ PSBoundParameters'可能只包含明确提供的参数,取决于定义。那么应该有一种方法来获得*我所期望的所有参数和值*。 – stej 2010-05-12 06:51:19

+0

考虑您提出的解决方案:您的代码比'SomeFuncWithManyRequiredParams -p1 $ p1 -p2 $ p2 -p3 $ p3'更长。如果函数'SimplifiedFuncWithDefaultValues'中的所有参数都有默认值,那么我认为没有区别。 – stej 2010-05-12 06:55:23

+0

我没有看到通过自动变量获取所需信息的方法。也许你可能想要提交一个MS Connect建议。 – 2010-05-12 15:09:11

0

您可以使用类似下面的Add-Variable功能的辅助函数:无论如何,你可以通过修补$ PSBoundParameters变量如解决这个

function SimplifiedFuncWithDefaultValues { 
    param(
     [Parameter(Mandatory=$false)][string]$p1='default for p1', 
     [Parameter(Mandatory=$false)][string]$p2='default for p2', 
     [Parameter(Mandatory=$false)][string]$p3='default for p3', 
     ...other parameters 
    ) 

    $PSBoundParameters | Add-Variable p1, p2, p3 

    SomeFuncWithManyRequiredParams @PSBoundParameters 
} 

function Add-Variable { 
    param(
     [Parameter(Position = 0)] 
     [AllowEmptyCollection()] 
     [string[]] $Name = @(), 
     [Parameter(Position = 1, ValueFromPipeline, Mandatory)] 
     $InputObject 
    ) 

    $Name | 
    ? {-not $InputObject.ContainsKey($_)} | 
    % {$InputObject.Add($_, (gv $_ -Scope 1 -ValueOnly))} 
} 
5

我知道这个问题已经很老了,但我最近需要一些类似的东西(想要使用很多默认参数进行喷溅)。我想出了这个和它的工作非常好:

$params = @{} 
foreach($h in $MyInvocation.MyCommand.Parameters.GetEnumerator()) { 
    try { 
     $key = $h.Key 
     $val = Get-Variable -Name $key -ErrorAction Stop | Select-Object -ExpandProperty Value -ErrorAction Stop 
     if (([String]::IsNullOrEmpty($val) -and (!$PSBoundParameters.ContainsKey($key)))) { 
      throw "A blank value that wasn't supplied by the user." 
     } 
     Write-Verbose "$key => '$val'" 
     $params[$key] = $val 
    } catch {} 
} 

无耻提前插头:我决定把它变成一个blog post which has more explanation and a sample usage script