如何为一个采用单个数组参数的构造函数调用New-Object?

Tim*_*ith 51 arrays parameters powershell constructor

在PowerShell中,我想用来New-Object调用单参数.Net构造函数new X509Certificate2(byte[] byteArray).问题是,当我使用PowerShell的字节数组执行此操作时,我得到了

New-Object:找不到"X509Certificate2"的重载和参数count:"516".

Kei*_*ill 63

这种使用方法new-object应该有效:

$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate `
      -ArgumentList @(,$bytes)
Run Code Online (Sandbox Code Playgroud)

诀窍是PowerShell期待一组构造函数参数.当只有一个参数且它是一个数组时,它可能会混淆PowerShell的重载决策算法.上面的代码通过将字节数组放在只有一个元素的数组中来帮助它.

更新:在PowerShell> = v5中,您可以直接调用构造函数,如下所示:

$cert = [System.Security.Cryptography.X509Certificates.X509Certificate]::new($bytes)
Run Code Online (Sandbox Code Playgroud)

  • 两个狡辩(仅此而已):`(, $bytes)` 足以构造数组;虽然“@(...)”最终的工作原理是相同的,但它没有必要并且效率较低,因为它构造了_另一个_数组(尽管在实践中这几乎不重要)。问题不在于构造函数重载解析,而在于 PowerShell 的标准参数绑定:“-ArgumentList”是“[object[]]”类型,因此如果您传递一个数组(或类似数组)的参数,该数组的元素成为传递给构造函数的_单独_参数;额外的数组包装器避免了这种情况。 (2认同)

Tim*_*ith 10

令我惊讶的是,我尝试了这个,它似乎有效:

[byte[]] $certPublicBytes = something
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate] $certPublicBytes
return $cert
Run Code Online (Sandbox Code Playgroud)

我还不知道它的作用是什么,所以你的解释性评论是值得赞赏的.:)

(注意:我发现使用方括号类型名称,如上所述,也可能导致其他错误,例如'无法转换值'System.Byte []"键入"System.Security.Cryptography.X509Certificates .X509Certificate".错误:"无法找到请求的对象.'基思推荐的显式新对象方法似乎更好!)

  • 通过将数组强类型为[byte []]而不是无类型(实际上是[object []]),您可以在选择正确的构造函数时消除所有歧义.如果没有可用的隐式或显式转换,PowerShell将在执行转换时查找构造函数. (8认同)