似乎调用Powershell脚本块(通过调用.Invoke()
方法)总是生成一个集合。具体来说,是
System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]
即使调用空脚本块({}.Invoke()
)也会返回一个集合。使用调用运算符(&
)调用相同的脚本块会产生正常预期的返回值(标量或[object[]]
)。
如果你需要一个集合而不是一个数组,这会很方便,但它似乎有点违反直觉。
有谁知道它为什么会这样?
编辑:
我知道有两种不同的调用,.Invoke()
和.InvokeReturnAsIs()
来自阅读语言规范。那是我第一次注意到它。
我只是不明白命名约定背后的原因以及它的机制似乎有效。查看文档,我认为默认的调用方法不是在Powershell中调用scriptblock时使用的方法。似乎.InvokeReturnAsIs()
只返回一个对象流,然后如果有多个对象,则Powershell将其包装到一个对象数组中,如果只有一个对象则将其包装为标量,如果没有,则创建一个空对象,如如果那里有一个隐含的管道。使用.Invoke()
始终返回一个集合,Powershell将其作为集合保留。
答案 0 :(得分:10)
看起来是这两种方法之间的区别:
调用 - 使用指定的参数调用脚本块, 将结果作为PSObject对象返回。
InvokeReturnAsIs - 使用指定的参数运行脚本块。 此方法返回原始(未包装)结果对象,以便它可以 更有效率。
<强>调用强>
$code = {"a"}
$code.Invoke().Gettype().FullName
输出:
System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]
<强> InvokeReturnAsIs 强>
$code.InvokeReturnAsIs().GetType().FullName
输出:
System.String
答案 1 :(得分:5)
我的猜测是团队希望与PowerShell.Invoke()
API保持一致,.NET Design Guidelines会返回Collection<PSObject>
。这个C#签名使客户端更容易使用0,1或N个返回值,而不必担心检查null以及返回的对象是否被包装。
来自{{3}}:
不要从集合属性或方法返回空值 返回集合。返回一个空集合或一个空数组 代替。
你可以说,为什么不回归object
。然后我将不得不反对null
然后我必须测试它是否实现ICollection
以确定我是否有标量或集合。从C#dev的角度来看,这是一个呕吐(原谅韵律)。 : - )
答案 2 :(得分:1)
因为这是它的设计目标,而且有另一种选择!
Invoke
- 使用指定的参数调用脚本块,将结果作为PSObject对象的(集合)返回。
InvokeReturnAsIs
- 使用指定的参数运行脚本块。此方法返回原始(未包装的)结果对象,以便更有效。
此外,{}.invoke()
返回null,因此我不知道您在哪里获得的印象甚至会返回一个集合。