12

In PowerShell v3.0 wurde PSCustomObject eingeführt. Es ist wie PSObject, aber besser. Neben anderen Verbesserungen (zB Eigentumsordnung erhalten bleibt), Objekt von hashtable Erstellung vereinfacht:PowerShell-Typ Beschleuniger: PSObject vs PSCustomObject

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

Nun scheint es offensichtlich, dass diese Aussage:

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

würde die gleiche Art und Weise arbeiten, weil PSCustomObject eine ist "Alias" für vollständigen Namespace + Klassennamen. Stattdessen ich eine Fehlermeldung erhalten:

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

I aufgeführten Beschleuniger für beide Arten von Objekten:

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

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

und entdeckt, dass beide die gleiche PSObject Klasse verweisen - dies hat bedeuten, dass Beschleuniger mit einem Bündel tun können von anderen Sachen als nur den Code kürzer zu machen.

Meine Fragen zu diesem Thema sind:

  1. Haben Sie zwischen der Verwendung eines Beschleunigers vs mit vollständigen Typnamen einige interessante examaples Unterschiede haben?
  2. Soll der vollständige Typname vermieden werden, wenn ein Beschleuniger als allgemeine Best Practice verfügbar ist?
  3. Wie überprüfen, vielleicht mit Reflektion, wenn ein Beschleuniger andere Dinge tut als nur auf die zugrunde liegende Klasse zu zeigen?
+4

Wenn Sie 'System.Management.Automation.Language.Compiler dekompilieren.VisitConvertExpression', dann können Sie sehen, dass es eine spezielle Behandlung für drei Typennamen gibt: 'ordered',' PSCustomObject' und 'ref'. – PetSerAl

Antwort

5

Mit Blick auf den statischen Methoden:

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... 

Der Beschleuniger hat ein paar neue statische Methoden hinzugefügt. Ich vermute, dass es eines davon als Konstruktor benutzt.

2

[PSObject] und [PSCustomObject] sind Aliase für denselben Typ - System.Management.Automation.PSObject. Ich kann nicht sagen, dass es einen guten Grund dafür gibt, aber es deutet zumindest auf zwei verschiedene Zwecke hin, und vielleicht ist das Grund genug.

System.Management.Automation.PSObject wird zum Umbrechen von Objekten verwendet. Es wurde eingeführt, um eine gemeinsame Reflektions-API über jedes Objekt bereitzustellen, das PowerShell umschließt - .Net, WMI, COM, ADSI oder einfache Eigenschaftensäcke.

System.Management.Automation.PSCustomObject ist nur ein Implementierungsdetail. Wenn Sie ein PSObject erstellen, muss das PSObject etwas umbrechen. Bei Objektbeuteln ist das umschlossene Objekt System.Management.Automation.PSCustomObject.SelfInstance (ein internes Element). Diese Instanz ist vor der normalen Verwendung von PowerShell verborgen. Die einzige Möglichkeit zur Beobachtung besteht in der Reflektion.

Property-Taschen sind in vielfältiger Weise in Powershell erstellt:

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

Beide o1 $ und darüber o2 $ wird eine Instanz von PSObject und die PSObject wird PSCustomObject.SelfInstance wickeln. PSCustomObject.SelfInstance wird intern in PowerShell verwendet, um den Unterschied zwischen einer einfachen Eigenschaftstasche und dem Umschließen eines anderen Objekts zu ermitteln.

+0

Hallo Jason. Sowohl "Get-Member" als auch ".GetType()" melden sowohl $ o1 als auch $ o2 als Instanzen von PSCustomObject anstelle von PSObject. –

+0

Wenn ich jedoch ein drittes Objekt als '$ o3 = [psobject] @ {Prop1 = 42}' erstelle, ist dieses Objekt anders. –

+1

Mein Punkt ist, dass die obige Antwort verwirrend ist, weil in der Powershell '[psobject]' und '[pscustomobject]' sicher nicht das gleiche tun. –