C# Powershell Cmdlet 中的互斥参数集:为什么这会模棱两可?

Sets of mutually exclusive parameters in C# Powershell Cmdlets: Why is this ambiguous?

所以我最初问这个是用 PowerShell 编写的 cmdlet,请参阅:

该问题的答案有效,但仅适用于 PowerShell 脚本 cmdlet。所以这里又是一个问题,但是对于 C# cmdlets ...

我一直在尝试让多组互斥起作用。 我希望“宽度”与“WidthReset”互斥,“高度”与“HeightReset”互斥。

C# cmdlet 的帮助显示:

    Get-ArgTest [-Width <Object>] [-Height <Object>] [<CommonParameters>]
    Get-ArgTest [-Width <Object>] [-HeightReset] [<CommonParameters>]
    Get-ArgTest [-Height <Object>] [-WidthReset] [<CommonParameters>]
    Get-ArgTest [-WidthReset] [-HeightReset] [<CommonParameters>]

PS cmdlet 的帮助显示:

PS C:\> .\get-ArgTestPs.ps1 -?
get-ArgTestPs.ps1 [-Width <int>] [-Height <int>] [<CommonParameters>]
get-ArgTestPs.ps1 [-Width <int>] [-HeightReset] [<CommonParameters>]
get-ArgTestPs.ps1 [-Height <int>] [-WidthReset] [<CommonParameters>]
get-ArgTestPs.ps1 -WidthReset -HeightReset [<CommonParameters>]

看下面的代码。

现在Get-ArgTest -Width 5好像有歧义

为什么这与直接在 PowerShell 中实现的 cmdlet 不同?

示例输出:

PS C:\> Get-ArgTest -Width 5 -HeightReset
Begin!
HELLO, Width=5, Height=, WidthReset=False, HeightReset=True
PS C:\> Get-ArgTest -Width 5
Get-ArgTest: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
PS 

测试:

## Try each combination
# First, just the values
Get-ArgTest                                                            # FAIL
Get-ArgTest -Width 2                                                   # FAIL
                                                                       
Get-ArgTest          -Height 4                                         # FAIL
Get-ArgTest -Width 2 -Height 4                                         
                                                                       
# Values and the opposite reset                                        
Get-ArgTest -Width 2                         -HeightReset              
Get-ArgTest          -Height 4   -WidthReset                           
                                                                       
# The Resets                                                           
Get-ArgTest                      -WidthReset -HeightReset              
Get-ArgTest                      -WidthReset -HeightReset:$False       
Get-ArgTest                      -WidthReset:$False -HeightReset:$True 
                                                                       
Get-ArgTest                      -WidthReset
Get-ArgTest                                  -HeightReset

C#代码是:

[Cmdlet("Get", "ArgTest")]
    [CmdletBinding(DefaultParameterSetName = "A")]
    public class ArgTestCmdlet : PSCmdlet
    {
        [Parameter(ParameterSetName = "A")]
        [Parameter(ParameterSetName = "B")]
        public object Width;

        [Parameter(ParameterSetName = "C")]
        [Parameter(ParameterSetName = "A")]
        public object Height;

        [Parameter(ParameterSetName = "C")]
        [Parameter(ParameterSetName = "D", Mandatory = true)]
        public SwitchParameter WidthReset;

        [Parameter(ParameterSetName = "B")]
        [Parameter(ParameterSetName = "D", Mandatory = true)]
        public SwitchParameter HeightReset;

        // This method gets called once for each cmdlet in the pipeline when the pipeline starts executing
        protected override void BeginProcessing()
        {
            WriteObject("Begin!");
        }

        // This method will be called for each input received from the pipeline to this cmdlet; if no input is received, this method is not called
        protected override void ProcessRecord()
        {
        }

        // This method will be called once at the end of pipeline execution; if no input is received, this method is not called
        protected override void EndProcessing()
        {
            WriteObject($"HELLO, Width={Width}, Height={Height}, WidthReset={WidthReset}, HeightReset={HeightReset}");
        }
    }

CmdletBinding 属性用于在 script cmdlet(或有时称为“高级功能”)上声明 cmdlet-like 绑定行为。

对于二进制 cmdlet,您需要在 Cmdlet 装饰器中指定默认参数集名称:

[Cmdlet("Get", "ArgTest", DefaultParameterSetName = "A")]
public class ArgTestCmdlet : PSCmdlet
{
    // the rest stays the same ...
}