ArrayList 中的空元素导致 'Cannot bind argument to parameter' 错误

Null element in ArrayList causing 'Cannot bind argument to parameter' error

问题

在下面的代码 (PowerShell v2) 中调用函数 f $array 时,出现错误:

f : Cannot bind argument to parameter 'csvObject1' because it is null.

我的代码

$hash1 = @{
    dependent_name = 'ADDM-Fun-3';
}
$obj1  = New-Object -TypeName PSObject -Property $hash1
$array = [System.Collections.ArrayList]@( $obj1, $null )

function f () {
    Param(
        [parameter(Position=0, Mandatory=$true)]
        [System.Collections.ArrayList]$array
    )
    "Hello"
}

f $array 

问题

Powershell 为什么要这样做?这对我来说是一个设计缺陷 - 但也许我没有看到大局。

评论

我认为此错误的发生是因为 ArrayList 中的第二行是 $null。我对此 'finding' 感到有些震惊,因为:

  1. 我花了大约 4 个小时才找到这个问题。
  2. 这似乎暗示在函数中使用强类型定义不是一个好主意,因为它会导致 PowerShell 检查数组中的每个元素,这是一个意外的开销。
  3. 如果我从函数定义中删除 [System.Collections.ArrayList],问题就会消失。

不确定为什么 PowerShell 会生成异常,因为 null 是 ArrayList 的有效成员。但是,您可以通过允许空值来强制进行参数验证。

像这样:

[parameter(Position=0, Mandatory=$true)][AllowNull()][System.Collections.ArrayList] $array

那么就没有异常产生了

您应该按照 about_Functions_Advanced_Parameters help topic

中所述使用 AllowNullAttribute
Param
(
    [Parameter(Position=0, Mandatory=$true)]
    [AllowNull()]
    [System.Collections.ArrayList]$array
) 

这是某种防御性编程。 PS 流水线时自动解包数组和 hastables。全局思考 - 当您将一堆服务器名称传递给函数时,您不希望其他服务器名称列表中的服务器名称为空。