12

In PowerShell v3.0 PSCustomObject è stato introdotto. È come PSObject, ma meglio. Tra gli altri miglioramenti (ad esempio, ordine proprietà di essere conservato), la creazione di oggetto dalla tabella hash è semplificata:Acceleratori di tipo PowerShell: PSObject vs PSCustomObject

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

ora sembra ovvio che questa dichiarazione:

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

funzionerebbe allo stesso modo, perché PSCustomObject è un "alias" per spazio dei nomi completo + nome classe. Invece ottengo un errore:

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

ho elencato acceleratori per entrambi i tipi di oggetti:

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

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

e ha scoperto che entrambi riferimento allo stesso PSObject classe - questo deve significare che l'uso di acceleratori può fare un mucchio di altre cose oltre a rendere il codice più breve.

Le mie domande per quanto riguarda questo problema sono:

  1. Vuoi inserire altri examaples interessanti differenze tra l'utilizzo di un acceleratore vs utilizzando il nome completo di tipo?
  2. È necessario evitare l'uso del nome completo quando è disponibile un acceleratore come procedura consigliata generale?
  3. Come verificare, magari utilizzando la riflessione, se un acceleratore fa altro che puntare semplicemente alla classe sottostante?
+4

Se si decompila 'System.Management.Automation.Language.Compiler.VisitConvertExpression', allora puoi vedere che ci sono gesti speciali per tre nomi di tipo: 'ordered',' PSCustomObject' e 'ref'. – PetSerAl

risposta

5

Guardando i metodi statici:

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

Il tipo di acceleratore ha un paio di nuovi metodi statici aggiunto. Sospetto che stia utilizzando uno di questi come costruttore.

2

[PSObject] e [PSCustomObject] sono alias per lo stesso tipo - System.Management.Automation.PSObject. Non posso dire che ci sia una buona ragione per questo, ma è almeno indicativo di due diversi scopi, e forse è una ragione sufficiente.

System.Management.Automation.PSObject viene utilizzato per avvolgere oggetti. È stato introdotto per fornire un'API di riflessione comune su qualsiasi oggetto che PowerShell integra: .Net, WMI, COM, ADSI o sacchetti di proprietà semplici.

System.Management.Automation.PSCustomObject è solo un dettaglio di implementazione. Quando crei un oggetto PSObject, PSObject deve avvolgere qualcosa. Per i sacchetti di proprietà, l'oggetto spostato è System.Management.Automation.PSCustomObject.SelfInstance (un membro interno). Questa istanza è nascosta dal normale utilizzo di PowerShell, l'unico modo per osservarlo è con la riflessione.

borse di proprietà sono creati in diversi modi in PowerShell:

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

Sia $ o1 e o2 $ sopra sarà un'istanza di PSObject, e il PSObject saranno avvolgere PSCustomObject.SelfInstance. PSCustomObject.SelfInstance viene utilizzato internamente in PowerShell per indicare la differenza tra un semplice contenitore di proprietà e il wrapping di qualsiasi altro oggetto.

+0

Ciao Jason. Sia 'Get-Member' che' .GetType() 'riportano sia $ o1 che $ o2 come istanze di PSCustomObject piuttosto che PSObject. –

+0

Se, tuttavia, creo un terzo oggetto come '$ o3 = [psobject] @ {Prop1 = 42}', quell'oggetto è diverso. –

+1

Il mio punto è che la risposta sopra è confusa, perché in powershell '[psobject]' e '[pscustomobject]' sicuramente non agiscono allo stesso modo. –