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 ...
}
所以我最初问这个是用 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 ...
}