ParameterSetName和Positions。拾取错误的设置

时间:2015-03-19 19:47:54

标签: powershell overloading

我正在尝试执行类似于

的重载样式方法
// C#
public void Foo (string xmlFilePathAndName, 
                 string environment, 
                 bool preventWrite) {}

public void Foo (string xmlFilePathAndName, 
                 string xmlTransformFilePathAndName, 
                 string environment, 
                 bool preventWrite) {}

基本上我写过这个。

[CmdletBinding(DefaultParameterSetName="default")]
param(

    [Parameter(Mandatory=$true, ParameterSetName='default', Position=0)] 
    [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=0)] 
    [string] $xmlFilePathAndName,

    [Parameter(Mandatory=$true, ParameterSetName='default', Position=1)]
    [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=2)] 
    [string] $environment,

    [Parameter(Mandatory=$false, ParameterSetName='default', Position=2)]
    [Parameter(Mandatory=$false, ParameterSetName='Overload1', Position=3)] 
    [switch] $preventWrite,

    [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=1)]
    [string] [alias('xdt')] $xmlTransformFilePathAndName

)


switch($PsCmdlet.ParameterSetName){
    "default" {  
        "default"
        break
    }
    "Overload1" {  
        "Overload1"
        break
    }
}

这是我的测试电话
注意:重要的是$environment需要在默认情况下排在第二位,在$xmlTransformFilePathAndName存在时需要排在第三位。

Invoke-XmlDocTransform "c:\somepath\web.config" 'local'  #expect Default
# result: Default     [PASSED]

Invoke-XmlDocTransform "c:\somepath\local.xml""c:\somepath\global.xml" 'local' -preventWrite # expect Overload1
# result: Default     [FAILED]

# I never want to use the below approach.
Invoke-XmlDocTransform "c:\somepath\local.xml" -xdt "c:\somepath\global.xml" 'local' -preventWrite # expect Overload1
# result: Overload1   [PASSED]

请注意,在第二个电话中,我没有得到预期的结果,但在第三个电话中,我是。

我真的不想添加-xdt参数声明以使其工作,我宁愿让它只是服从位置参数... IE:如果有一个字符串在第三个位置,使用过载,否则,不要。

有什么办法可以做我想做的事吗?

2 个答案:

答案 0 :(得分:1)

我无法解释这种行为,但如果您将参数顺序更改为此参数集,则按照您希望的方式处理AFAICS:

  1. 两个集合中必需的参数
  2. 其他强制性参数
  3. 可选参数
  4. 代码:

    [CmdletBinding(DefaultParameterSetName="default")]
    param(
        [Parameter(Mandatory=$true, ParameterSetName='default', Position=0)] 
        [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=0)] 
        [string] $xmlFilePathAndName,
    
        [Parameter(Mandatory=$true, ParameterSetName='default', Position=1)]
        [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=1)] 
        [string] $environment,
    
        [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=2)]
        [string] [alias('xdt')] $xmlTransformFilePathAndName,
    
        [Parameter(Mandatory=$false, ParameterSetName='default', Position=2)]
        [Parameter(Mandatory=$false, ParameterSetName='Overload1', Position=3)]
        [switch] $preventWrite
    )
    

    输出:

    PS C:\> .\test.ps1 "c:\somepath\local.xml" 'local' "c:\somepath\global.xml"
    Overload1
    PS C:\> .\test.ps1 "c:\somepath\local.xml" 'local' "c:\somepath\global.xml" -preventWrite
    Overload1
    PS C:\> .\test.ps1 "c:\somepath\local.xml" 'local' -preventWrite
    default
    PS C:\> .\test.ps1 "c:\somepath\local.xml" 'local'
    default

答案 1 :(得分:0)

我不会说我确切知道位置参数集是如何工作的,但我通过删除第二个位置并为每个参数提供唯一的位置编号来使代码工作。

function Invoke-XmlDocTransform
{
    [CmdletBinding(DefaultParameterSetName="default",
                   PositionalBinding=$true)]
    param(

        [Parameter(Mandatory=$true, ParameterSetName='default', Position=0)] 
        [Parameter(ParameterSetName='Overload1')] 
        [string] $xmlFilePathAndName,

        [Parameter(Mandatory=$true, ParameterSetName='default', Position=1)]
        [Parameter(ParameterSetName='Overload1')] 
        [string] $environment,

        [Parameter(Mandatory=$false, ParameterSetName='default', Position=3)]
        [Parameter(ParameterSetName='Overload1')] 
        [switch] $preventWrite,

        [Parameter(Mandatory=$true, ParameterSetName='Overload1', Position=2)]
        [string] [alias('xdt')] $xmlTransformFilePathAndName

    )


    switch($PsCmdlet.ParameterSetName)
    {
        "default"
        {  
            "default"
            break
        }
        "Overload1"
        {  
            "Overload1"
            break
        }
    }

    $PSBoundParameters
}

这给了我结果

Invoke-XmlDoctransform 'this' 'that'
Default

Invoke-XmlDocTransform 'this' 'that' -PreventWrite
Default

Invoke-XmlDocTransform 'this' 'that' 'them'
Overload1

Invoke-XmlDocTransform 'this' 'that' 'them -PreventWrite
Overload1