为什么不能根据 [字符串] vs [哈希表] vs [pscustomobject] 解析参数集?



考虑这个函数:

function Test-Discrimination
{
    [CmdletBinding()]
    param
    (
        [parameter(ValueFromPipeline = $true,
                    Mandatory = $true,
                    ParameterSetName = 'string')]
        [string]
        $String,
        [parameter(ValueFromPipeline = $true,
                    Mandatory = $true,
                    ParameterSetName = 'hashtable')]
        [hashtable]
        $Hashtable,
        [parameter(ValueFromPipeline = $true,
                    Mandatory = $true,
                    ParameterSetName = 'pscustomobject')]
        [pscustomobject]
        $PsCustomObject
    )
    process
    {
        $PSCmdlet.ParameterSetName
    }
}

管道[pscustomobject]的行为正如我所期望的:

PS C:> New-Object pscustomobject | Test-Discrimination
pscustomobject

但是,管道[string]抛出一个异常:

PS C:> 'string' | Test-Discrimination
Test-Discrimination : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:12
+ 'string' | Test-Discrimination
+            ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (string:String) [Test-Discrimination], Paramete 
   rBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Test-Discrimination

[hashtable]:也是如此

PS C:> @{} | Test-Discrimination
Test-Discrimination : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:7
+ @{} | Test-Discrimination
+       ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (System.Collections.Hashtable:Hashtable) [Test- 
   Discrimination], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Test-Discrimination

添加DefaultParameterSetName='hastable'会导致[hashtable]而不是[string]正确解析。

我在解释Trace命令的输出方面没有经验。我确实注意到[string]的输出包括以下行:

BIND arg[string]到param[PsCustomObject]SUCCESSFUL

看起来PowerShell正在考虑将[string]作为[PsCustomObject]。但CCD_ 10评估为CCD_。

这一切都给我留下了以下问题:

  1. 为什么PowerShell不能根据[string][pscustomobject]之间的类型差异来选择参数集
  2. 原因是PowerShell认为[string][pscustomobject]吗?如果是这样,为什么会这样
  3. 有没有一种变通方法可以让我使用不同的类型来选择不同的参数集

我相信这是因为任何东西都可以被广播到[PSObject]([PSCustomObject](。PowerShell尝试将值合并到目标类型。这就是为什么当你有一个[int]的参数时,你可以传递"5",它会起作用,或者为什么当你的参数是[ipaddress]时,你能给它一个字符串"1.2.3.4"

因此,在参数绑定过程中,当您传递[string][hashtable]时,会发生的情况是它成功地将其绑定到[pscustomboject]参数,以及(至少(其他参数之一,因此它无法解析集合。

我不认为有任何方法可以关闭这种行为或使其"更严格"。


顺便说一句,任何东西都可以被广播到[PSObject]的原因是,在PowerShell中,每个对象都已经是[PSObject]了!这也是您可以将成员添加到任何对象的任何实例的原因。PowerShell使这一切变得非常透明,这就是为什么正如您所说,它在这种情况下(以及其他一些情况下(违反了最小惊喜原则。

如果您从C#中与PowerShell进行交互,那么[PSObject]中的所有内容都会变得更加明显(在许多情况下也很烦人(,这就是我第一次意识到这一点的原因。

最新更新