2012-01-27 32 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[]])が生成されます。

これは、配列の代わりにコレクションが必要な場合に便利ですが、直感的ではないようです。

誰でもこのように動作する理由を知っていますか?

編集:

私は2つの異なる呼び出し、言語仕様を読んでから.Invoke().InvokeReturnAsIs()があります知っていました。それは私が最初に気づいたことです。

命名規則の背後にある理由と、その仕組みがどのように動作するかは分かりません。ドキュメントを見ると、デフォルトの呼び出しメソッドと思われるものは、Powershellでscriptblockが呼び出されたときに使用されるものではありません。 .InvokeReturnAsIs()はオブジェクトのストリームを返すだけで、Powershellはオブジェクトが複数ある場合はオブジェクト配列に、オブジェクトが1つのみの場合はスカラーとして、また暗黙の場合は存在しない場合はnullオブジェクトを作成します。そこにパイプライン。 .Invoke()を使うと常にコレクションが返され、Powershellはそれをコレクションとして残します。

答えて

8

は、これらの2つの方法の間の差であることになります

起動 - は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

+0

'Get-Member -InputObject({} .invoke())'は、コレクションを返します。逆に '$ null -eq {} .Invoke()'は '$ False'を返します。返されるコレクションは_empty_です。そのため、コンソールには何も出力されません。 – mklement0

4

私の推測では、チームがCollection<PSObject>返しPowerShell.Invoke() API、と一致するように望んでいたということです。このC#シグネチャは、クライアントが0、1、またはNの戻り値を消費しやすくなり、nullのチェックや返されたオブジェクトがラップされたかどうかを心配する必要がなくなります。 .NET Design Guidelinesから

は、コレクションのプロパティから、またはコレクションを返すメソッド からNULL値を返しません。代わりに空のコレクションまたは空の配列 を返します。

あなたは、ちょうどobjectを返さないと言うことができます。その後、私はnullに対してしなければならないし、私はそれがICollectionスカラーまたはコレクションを持っていたかどうかを判断するために実装されているかどうかを確認するためにテストする必要があります。 C#のdevの視点から、これはspew(韻を赦してください)です。 :-)

関連する問題