2

は、関数のオーバーロードは、歴史的に、各過負荷が単純署名の上にパラメータの一部量を加算し、次のようなものが登場している:PowerShellでPowershell:C#-style関数はパラメータセットでオーバーロードされますか? C#の

public void Initialize(int version); 
public void Initialize(int version, string workspaceName); 
public void Initialize(int version, string workspaceName, Path workspaceRoot, bool force); 

を、このような過負荷は不可能です。ただし、System.Management.Automation.ParameterAttributeのParameterSetNameプロパティを使用すると、関数オーバーロードの近似値が提供されます。これにより、パラメータを特定のパラメータセットのメンバとして宣言することができ、関数に対して別々のシグネチャを効果的に定義することができます。例のこの基本的なタイプは、パラメータの複雑な用途に信じられないほどではありません

PS D:\.ws> get-help test-param 
test-param [[-i] <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 
test-param [[-d] <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 

:以下を得

function test-param 
{ 
[CmdletBinding(DefaultParametersetName="p2")] 
param( 
[Parameter(ParameterSetName="p1",Position=0)] 
[String] 
$d, 

[Parameter(ParameterSetName="p2", Position=0)] 
[String]$i 
) 
    switch ($PsCmdlet.ParameterSetName) 
{ 
    "p1" { Write-Host ([DateTime]$d); break} 
    "p2" { Write-Host ([INT]$i); break} 
    } 
} 

が取得ヘルプこの機能には:ほとんどのParameterSetName examplesで見つかった単純な場合には、このようなものですただし、パラメータセットは完全に相互排他的です。しかし、いくつかのパラメータをすべてのパラメータセットのメンバーにしたい場合はどうすればよいでしょうか?経験豊富なユーザーは、これが特別な "AllParameterSets"パラメータセットの場合であることを示唆するかもしれません。これは、パラメータセットが指定されていない場合、MSDNによればデフォルトです。ただし、次の点を考慮してください「AllParameterSetsは」パラメータセットとして指定されている場合

PS D:\.ws>  function test-param 
{ 
    [CmdletBinding(DefaultParametersetName="p2")] 
    param 
    ( 
     [Parameter(ParameterSetName="p1",Position=0)] 
     [String] 
     $d, 
     [Parameter(ParameterSetName="p2", Position=0)] 
     [String]$i, 
     [Parameter(ParameterSetName="AllParameterSets")] 
     [String]$x 
    ) 
} 

PS D:\.ws> get-help test-param 
test-param [[-i] <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 
test-param [[-d] <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 
test-param [-x <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 

はどうやら、それは1想像のとおり、すべてのパラメータセットに含まれていない事実です。これは、宣言を省略すると分かります。

ここで、$ xパラメータは、私たちが期待するようなすべての関数シグニチャに表示されます。

最後に、最も複雑なケースです。 1つのパラメータをすべてではなく一部のシグネチャに表示したい場合はどうすればよいですか?元の例で与えられたworkspaceNameパラメータは、この説明に適合します。おそらく、このソリューションの鍵は、複数のパラメータプロパティをparamブロックの各パラメータに対して宣言できることです。これにより、各シグネチャに対してパラメータセットを確立し、それが属する各セットのParameterアトリビュートで各パラメータを修飾することができます。

PS D:\.ws> function Initialize-Something 
{ 
    [CmdletBinding()] 
    param 
    (
     [Parameter(ParameterSetName="version")] 
     [Parameter(ParameterSetName="workspaceName")] 
     [Parameter(ParameterSetName="createWorkspace")] 
     [int] $Version, 
     [Parameter(ParameterSetName="workspaceName")] 
     [Parameter(ParameterSetName="createWorkspace")] 
     [string] $WorkspaceName, 
     [Parameter(ParameterSetName="createWorkspace")] 
     [string] $WorkspaceRoot, 
     [Parameter(ParameterSetName="createWorkspace")] 
     [switch] $Force 
    ) 
} 

PS D:\.ws> get-help initialize-something 
Initialize-Something [-Version <Int32>] [-WorkspaceName <String>] [-WorkspaceRoot <String>] [-Force] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 
Initialize-Something [-Version <Int32>] [-WorkspaceName <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 
Initialize-Something [-Version <Int32>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>] 

PS D:\.ws> initialize-something -workspacename "test" 
Initialize-Something : Parameter set cannot be resolved using the specified named parameters. 
At line:1 char:21 
+ initialize-something <<<< -workspacename "test" 
    + CategoryInfo   : InvalidArgument: (:) [Initialize-Something], ParameterBindingException 
    + FullyQualifiedErrorId : AmbiguousParameterSet,Initialize-Something 

Powershellは、WorkspaceNameが複数の署名に表示されるため、パラメータセットを判断できないと主張しています。レコードの場合、これは-Versionのみを指定する場合や、最も複雑なもの以外のシグネチャを指定する場合にも発生します。これは[CmdletBinding(DefaultParameterSetName = "version")]などで多少緩和できますが、適切な解決策ではありません。

この後、私の質問:どのように私が探している署名の種類を達成することができますか? -VersionMode、-WorkspaceNameMode、-CreateWorkspaceModeなどの過度に明示的なスイッチを作成して、どのモードを実行するかを指定する必要があります。これは基本的にパラメータセット検出の正当性を否定しますか?おそらくモード列挙型ですか?これは、ParameterAttributeのMandatoryおよびPositionプロパティを使用していくらかの優雅さによって行うことができますか?

ありがとうございます!

答えて

5

C#関数のオーバーロードをエミュレートしようとする場合、最も簡単な方法は、「オプション」パラメータを単に許可することです。:呼び出しで指定されていない

function Initialize([int]$version, [string]$workspaceName, [string]workspaceRoot, [switch]Force) 

パラメータは(スイッチが$ falseにデフォルト設定されます)の$ nullにデフォルト設定されます。また、そのようなパラメータのデフォルト値を提供することができます。

function Initialize([int]$version, [string]$workspaceName = $(<script here>), [string]workspaceRoot, [switch]Force) 
+0

あなたは彼らだけ現れることができるということが、そのような、宣言的パラメータ間の依存関係を定義する方法を知っていますか一緒に?この場合の例は少しでも単純化されていますが、興味があるのは、パラメータの一部を一緒に表示するか、まったく表示しないようにパラメータを定義することが可能かどうかということです。例えば、いくつかのパラメータセット定義がなければ、それ自体で-Forceスイッチを使うことができます。これらの属性を使ってpowershellに私にこれをさせたいときには、すべてのパラメータの解析とエラー検出を書きます。 – bwerks

+0

これを行う方法はパラメータセットです。複数のパラメータセットにパラメータを設定し、パラメータにパラメータセットを指定しない場合は、すべてのパラメータセットで使用できるようになります。また、PowerShellが指定されたパラメータからパラメータセットを判断できない場合、 '[CmdletBinding()]'属性でデフォルトのパラメータセットを指定することもできます。 –

1

2つのパラメータセットについて覚えておくべき重要なことは、Windows PowerShellの実行時には、特定の入力のための設定パラメータを1つだけ使用していることであり、各パラメータセットを持っていなければならないことそのパラメータセットに固有の少なくとも1つのパラメータ。あなたは-WorkspaceRoot状の第2パラメータを指定する必要があり、それが動作しますあなたの場合は

initialize-something -workspacename "test" -WorkspaceRoot "test2"

関連する問題