我有一种我不明白的奇怪行为。创建的所有数组不都是相等的吗?
\n$a1=[object[]]::new(15)\n$a1.gettype()\n\nIsPublic IsSerial Name BaseType\n-------- -------- ---- --------\nTrue True Object[] System.Array\n\n$a1.length\n15\n\n0..14|%{$a1[$_]=$_}\nRun Code Online (Sandbox Code Playgroud)\n第 10 个元素的字符串格式按预期工作。
\n'{10}' -f $a1\n10\nRun Code Online (Sandbox Code Playgroud)\n但...
\n$a2=new-object object[] 15\n$a2.gettype()\n\nIsPublic IsSerial Name BaseType\n-------- -------- ---- --------\nTrue True Object[] System.Array\n\n\n$a2.length\n15\n\n0..14|%{$a2[$_]=$_}\nRun Code Online (Sandbox Code Playgroud)\n完全相同的字符串格式化请求会引发错误,就好像$a2数组太小一样
'{10}' -f $a2\nErreur lors de la mise en forme d\xe2\x80\x99une cha\xc3\xaene : L'index (de base z\xc3\xa9ro) doit \xc3\xaatre sup\xc3\xa9rieur ou \xc3\xa9gal \xc3\xa0 z\xc3\xa9ro et inf\xc3\xa9rieur \xc3\xa0 la taille de la liste des arguments..\nAu caract\xc3\xa8re Ligne:1 : 1\n+ '{10}' -f $a2\n+ ~~~~~~~~~~~~~\n + CategoryInfo : InvalidOperation : ({10}:String) [], RuntimeException\n + FullyQualifiedErrorId : FormatError\nRun Code Online (Sandbox Code Playgroud)\n我错过了什么吗?我哪里错了?
\n该行为是一个已知的错误:
由于New-Object是cmdlet(命令)而不是表达式(例如[object[]]::new(15)),因此其输出对象包装在[psobject]实例中。
通常,这些不可见的[psobject]包装器是良性的,并且包装器呈现得好像它是被包装的对象本身。
但是,在某些情况下,此类包装器的存在会干扰功能,例如您的情况:
该-f运算符无法识别[psobject]这样的 -wrapped 数组,这会导致您看到的问题:
用人工包裹的数组来模拟问题[psobject]:
# !! Error:
# "Index (zero based) must be greater than or equal to zero and
# less than the size of the argument list."
# The [psobject]-wrapped array is treated as a *single* object so -f
# sees no *2nd* value ({1})
# Omitting the [psobject] cast works as expected.
'{1}' -f [psobject] ('a', 'b')
# Ditto, with New-Object,
# which *invariably and implicitly* returns the array in a [psobject] wrapper.
'{1}' -f (New-Object string[] 2)
Run Code Online (Sandbox Code Playgroud)
相关 GitHub 问题:
GitHub 问题 #14355:手头的错误。
GitHub 问题 #5579:一般讨论和情境[psobject]包装导致问题的其他情况。
解决方法:
正如您所注意到的,通过PowerShell在所有 .NET 类型(需要 v5+ 的 PowerShell)上公开的内在静态方法(例如)使用构造函数表达式,不会出现问题,因为此时不涉及不可见的包装器。::new()[object[]]::new(15)[psobject]
New-Object。在 PowerShell v4- 中,使用通过内部属性.psobject.BaseObject来解决该问题,该属性返回包装的数组:psobject
$a2 = (New-Object object[] 15).psobject.BaseObject
'{10}' -f $a2 # OK
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |