Accélérateurs de type PowerShell: PSObject vs PSCustomObject

dans PowerShell v3.0PSCustomObject a été introduit. C'est comme PSObject, mais en mieux. Parmi d'autres améliorations (par exemple l'ordre de propriété étant préservé), la création d'objet à partir du hashtable est simplifiée:

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

Maintenant, il semble évident que cette instruction:

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

fonctionnerait de la même façon, parce que PSCustomObject est un "alias" pour namespace complet + nom de classe. Au lieu de cela, j'obtiens une erreur:

ne peut pas convertir le " système.Collection.Hashtable " valeur du type "Système.Collection.Hashtable" pour "type de Système.Gestion.Automatisation.PSCustomObject".

j'ai énuméré les accélérateurs pour les deux types d'objets:

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

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

et a découvert que les deux font référence au même PSObject classe - cela signifie que l'utilisation d'accélérateurs peut faire un tas d'autres choses que simplement rendre le code plus court.

Mes questions concernant cette question sont:

  1. avez-vous quelques exemples intéressants de différences entre l'utilisation d'un accélérateur vs utilisation nom complet du type?
  2. devrait-on éviter d'utiliser le nom complet chaque fois qu'un accélérateur est disponible à titre de pratique exemplaire générale?
  3. Comment vérifier, peut-être en utilisant la réflexion, si un accélérateur fait autre chose que simplement pointer vers la classe sous-jacente?
13
demandé sur Adam Luniewski 2016-03-09 17:25:04

2 réponses

en Regardant les méthodes statiques:

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

l'accélérateur de type a quelques nouvelles méthodes statiques ajoutées. Je pense qu'il utilise l'un d'eux comme constructeur.

6
répondu mjolinor 2016-03-09 20:43:40

[PSObject] et [PSCustomObject] sont des alias pour le même type de système.Gestion.Automatisation.PSObject. Je ne peux pas dire qu'il y a une bonne raison à cela, mais c'est au moins évocateur de deux buts différents, et peut-être que c'est une raison suffisante.

Système.Gestion.Automatisation.PSObject est utilisé pour envelopper des objets. Il a été introduit pour fournir une api de réflexion commune sur tout objet que PowerShell enveloppe-.Net, WMI, COM, ADSI, ou simple propriété sac.

Système.Gestion.Automatisation.PSCustomObject n'est qu'un détail d'implémentation. Quand vous créez un PSObject, le PSObject doit envelopper quelque chose. Pour les sacs de propriété, l'objet enveloppé est le système.Gestion.Automatisation.PSCustomObject.SelfInstance (un membre interne. Cette instance est cachée de L'utilisation normale de PowerShell, la seule façon de l'observer est avec la réflexion.

Les sacs de propriétés sont créés de multiples façons dans PowerShell:

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

Les deux $o1 et $o2 ci-dessus sera une instance de PSObject, et le PSObject enveloppera PSCustomObject.SelfInstance. PSCustomObject.SelfInstance est utilisé en interne dans PowerShell pour faire la différence entre un simple sac de propriété et envelopper tout autre objet.

2
répondu Jason Shirk 2016-03-13 02:31:44