12

PowerShell v3.0でPSCustomObjectが導入されました。それはPSObjectのようですが、より良いです。その他の改善(例えば、プロパティの順序は保持されている)、ハッシュテーブルからオブジェクトを作成が簡略化されるなかで:PSCustomObjectがあるのでPowerShellタイプアクセラレータ:PSObjectとPSCustomObject

[System.Management.Automation.PSCustomObject]@{one=1; two=2;} 

、同じように動作します:

[PSCustomObject]@{one=1; two=2;} 

今では、この文があることは明らかと思われます完全な名前空間+クラス名の "エイリアス"。代わりに、私はエラーを取得する:

Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Management.Automation.PSCustomObject".

私は、オブジェクトの両方のタイプのアクセラレータ記載されている:

[accelerators]::get.GetEnumerator() | where key -Like ps*object 

    Key   Value 
    ---   ----- 
    psobject  System.Management.Automation.PSObject 
    pscustomobject System.Management.Automation.PSObject 

をし、両方が同じPSObjectクラスを参照することを発見した - これは、アクセラレータを使用して束を行うことができますことを意味していますコードを短くする以外のものがあります。この問題について

私の質問は以下のとおりです。

  1. あなたは完全なタイプ名を使用して対アクセラレータを使用しての違いをいくつかの興味深いexamaplesを持っていますか?
  2. アクセラレータが一般的なベストプラクティスとして利用可能であるときはいつでもフルタイプの名前を使用する必要がありますか?
  3. アクセラレータが基本クラスを指すだけでなく他のことをしているかどうかを、おそらくリフレクションを使って確認する方法はありますか?静的メソッドを見ると
+4

「System.Management.Automation.Language.Compiler」を逆コンパイルする場合。VisitConvertExpression'を実行すると、 'ordered'、' PSCustomObject'、 'ref'という3つの型名に対して特別な処理があることが分かります。 – PetSerAl

答えて

5

:型アクセラレータ

PS C:\> [PSCustomObject] | gm -Static -MemberType Method 



    TypeName: System.Management.Automation.PSObject 

Name   MemberType Definition               
----   ---------- ----------               
AsPSObject  Method  static psobject AsPSObject(System.Object obj)      
Equals   Method  static bool Equals(System.Object objA, System.Object objB)   
new    Method  psobject new(), psobject new(System.Object obj)     
ReferenceEquals Method  static bool ReferenceEquals(System.Object objA, System.Object o... 



PS C:\> [System.Management.Automation.PSCustomObject] | gm -Static -MemberType Method 



    TypeName: System.Management.Automation.PSCustomObject 

Name   MemberType Definition               
----   ---------- ----------               
Equals   Method  static bool Equals(System.Object objA, System.Object objB)   
ReferenceEquals Method  static bool ReferenceEquals(System.Object objA, System.Object o... 

新しい静的メソッドのカップルが追加されました。私はそれがコンストラクタとしてそれらの1つを使用していると思う。

2

[PSObject]と[PSCustomObject]は同じ型のエイリアスです(System.Management.Automation.PSObject)。それには正当な理由があるとは言えませんが、少なくとも2つの異なる目的が示唆されています。

System.Management.Automation.PSObjectは、オブジェクトをラップするために使用されます。 PowerShellが.NET、WMI、COM、ADSI、または単純なプロパティバッグをラップするオブジェクトに共通のリフレクションAPIを提供するために導入されました。

System.Management.Automation.PSCustomObjectは単なる実装の詳細です。 PSObjectを作成するとき、PSObjectは何かをラップする必要があります。プロパティバッグの場合、ラップされたオブジェクトはSystem.Management.Automation.PSCustomObject.SelfInstance(内部のメンバー)です。このインスタンスはPowerShellの通常の使用から隠されています。

プロパティバッグは、PowerShellで複数の方法で作成されます。

$o1 = [pscustomobject]@{Prop1 = 42} 
$o2 = new-object psobject -Property @{Prop1 = 42 } 

の$ o1とPSObjectのインスタンスになります上記のO2 $、およびPSObjectの両方がPSCustomObject.SelfInstanceをラップします。 PSCustomObject.SelfInstanceは、PowerShellで内部的に使用され、単純なプロパティバッグと他のオブジェクトをラップする違いを示します。

+0

こんにちはJason。 'Get-Member'と' .GetType() 'はどちらもPSObjectではなくPSoCustomObjectのインスタンスとして$ o1と$ o2の両方を報告します。 –

+0

しかし、第3のオブジェクトを '$ o3 = [psobject] @ {Prop1 = 42}'として作成すると、そのオブジェクトは異なります。 –

+1

PowerShellの '[psobject]'と '[pscustomobject]'は同じことをしないので、上記の答えが混乱しているという私の主張です。 –

関連する問題