Наборы взаимоисключающих параметров в командлетах C# Powershell: почему это неоднозначно?

Итак, я изначально задал этот вопрос для командлета, написанного в PowerShell, см.: Неоднозначный вопрос в Powershell .

Ответ на этот вопрос работает, но только для командлетов сценария PowerShell. Так вот опять вопрос, но для командлетов C#...

Я пытался заставить работать несколько наборов взаимных исключений. Я хочу, чтобы «Ширина» взаимоисключала «WidthReset», а «Высота» была взаимоисключающей с «HeightReset».

Справка по командлету C# показывает:

          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 показывает:

      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?

Пример вывода:

      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

Код С#:

      [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}");
        }
    }

1 ответ

В CmdletBindingАтрибут предназначен для объявления поведения связывания, подобного командлетам, для командлетов сценариев (или «расширенных функций», как их иногда называют).

Для двоичного командлета необходимо указать имя набора параметров по умолчанию в Cmdletвместо этого декоратор:

      [Cmdlet("Get", "ArgTest", DefaultParameterSetName = "A")]
public class ArgTestCmdlet : PSCmdlet
{
    // the rest stays the same ...
}
Другие вопросы по тегам