2012-01-27 58 views
3

似乎调用Powershell脚本块(通过调用.Invoke()方法)总是产生一个集合。具体地,类型为什么使用.Invoke()调用Powershell脚本块会返回一个集合?

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中调用脚本块时使用的方法。看起来,.InvokeReturnAsIs()只是返回一个对象流,然后如果有多个对象,则Powershell将其包装到对象数组中,如果只有一个对象,则将它包装到对象数组中,或者创建空对象(如果没有对象),就好像存在隐式管道在那里。总是使用.Invoke()返回一个集合,Powershell将其作为集合保留。

回答

8

看起来是这两种方法之间的区别:

调用 - 用指定的参数, 返回结果为PSObject对象调用的脚本块。

InvokeReturnAsIs - 运行带有指定参数的脚本块。 此方法返回原始(未包装的)结果对象,以便它可以更高效地使用 。

http://msdn.microsoft.com/en-us/library/system.management.automation.scriptblock_methods(v=vs.85).aspx

调用

$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

因为这就是它的设计做的,还有一个备用!

Invoke - 用指定参数调用脚本块,将结果作为(集合)返回给PSObject对象。

InvokeReturnAsIs - 运行带有指定参数的脚本块。此方法返回原始(未包装的)结果对象,以便它可以更高效。

另外,{}.invoke()返回null,所以我不知道你从哪里得到了即使返回一个集合的印象。

http://msdn.microsoft.com/en-us/library/system.management.automation.scriptblock.invokereturnasis(v=vs.85).aspx

+0

我得到了这样的想法,当我这样做时,它会收集:({} .invoke).gettype() – mjolinor 2012-01-27 11:16:39

+0

'Get-Member -InputObject({} .invoke())'也表明它也是返回一个集合;相反,'$ null -eq {} .Invoke()'返回'$ False'。返回的集合是_empty_,这就是为什么它在控制台中不产生输出。 – mklement0 2017-06-21 22:09:26

4

我的猜测是,球队希望能与PowerShell.Invoke() API,它返回一个Collection<PSObject>一致。这个C#签名使得客户端更容易消费0,1或N个返回的值,而不必担心检查null以及返回的对象是否被包装。

.NET Design Guidelines

不要从集合属性或返回集合方法 返回空值。改为返回空集合或空集合 。

你可以说那么为什么不只是返回object。那么我将不得不对null或不,然后我不得不测试,看它是否执行ICollection来确定我是否有标量或集合。从C#开发者的角度来看,这是一个难题(赦免韵)。 :-)

相关问题