9

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

4

3 回答 3

11

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

Invoke - 使用指定的参数调用脚本块,将结果作为 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]]

调用返回原样

$code.InvokeReturnAsIs().GetType().FullName

输出:

System.String
于 2012-01-27T05:08:36.957 回答
7

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

来自.NET 设计指南

不要从集合属性或返回集合的方法返回空值。而是返回一个空集合或一个空数组。

你可以说那为什么不直接返回object。然后我将不得不反对null或不反对,然后我必须测试它是否实现ICollection以确定我是否有一个标量或集合。从 C# 开发人员的角度来看,这是一个喷子(请原谅押韵)。:-)

于 2013-11-23T04:58:41.340 回答
1

因为这就是它的设计目的,而且还有一个替代方案!

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

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

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

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

于 2012-01-27T05:10:59.280 回答