我当前在Powershell中使用匿名函数,并且我注意到从System.ValueType到System.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
? 最佳答案
使用:
$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
解释为第一个也是唯一要整体传递给脚本块的参数。