我当前在Powershell中使用匿名函数,并且我注意到从System.ValueTypeSystem.Object时存在一个奇怪的转换问题。

请看以下示例:

$f = {
    param($InputArray)
    Write-Host "`$Arr Type During Call:" ($InputArray.GetType().FullName)
    Write-Host "`$Arr Contents During Call:" $InputArray
}

[object[]]$Arr = [object[]]@($true, $false)

Write-Host "`$Arr Type Before Call:" ($Arr.GetType().FullName)
Write-Host "`$Arr Contents Before Call:" $Arr "`n"

$f.Invoke($Arr)

以下示例将输出以下内容:



看起来Powershell将我的变量$Arr转换为System.Boolean类型。如果我强制参数为object[]类型,则会引入一个新问题:
$f = {
    param([object[]]$InputArray)
    Write-Host "`$Arr Type During Call:" ($InputArray.GetType().FullName)
    Write-Host "`$Arr Contents During Call:" $InputArray
}

[object[]]$Arr = [object[]]@($true, $false)

Write-Host "`$Arr Type Before Call:" ($Arr.GetType().FullName)
Write-Host "`$Arr Contents Before Call:" $Arr "`n"

$f.Invoke($Arr)

新更改将产生以下输出:



Powershell仅提供匿名函数作为数组的一个元素。这里发生了什么?
  • 为什么当我明确地给它一个boolean数组时,Powershell为什么将其转换为object
  • 即使我强制使用匿名函数的输入参数类型,为什么Powershell也不提供整个数组?
  • 最佳答案

    使用:

    $f.Invoke((, $Arr))
    

    或者,更特别地,PowerShell:
    & $f $Arr
    

    至于您尝试了什么:



    将数组$Arr的元素作为单个参数传递。
    由于您的脚本块$f仅定义了一个参数,因此只有$Arr的第一个元素绑定(bind)到该参数$InputArray
    (, ($Arr))通过将数组包装在辅助单元素数组中来解决该问题,然后$f.Invoke()解开包装,因此将$Arr作为单个参数传递。

    也就是说,鉴于调用语法会导致与PowerShell的命令语法混淆,因此在PowerShell中使用对象方法通常会很尴尬。

    通常,可能会停留在PowerShell命令和运算符的 Realm 。

    具体来说,PowerShell惯用的调用脚本块({ ... })的方法是使用&(调用运算符(在子范围内执行脚本块; .),点源运算符,(通常)直接在调用者的范围内执行)。
    &(和.)使用命令语法(参数解析模式),其中参数传递时不带括号,并用空格分隔,而不是,-有关更多信息,请参见this answer

    因此,& $f $Arr$Arr解释为第一个也是唯一要整体传递给脚本块的参数。

    10-05 20:31
    查看更多