12

W PowerShell v3.0 wprowadzono PSCustomObject. To jest jak PSObject, ale lepsze. Wśród innych usprawnień (np porządek nieruchomość jest zachowany), tworząc obiekt z hashtable jest uproszczona:Akceleratory typu PowerShell: PSObject vs PSCustomObject

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

Teraz wydaje się oczywiste, że to stwierdzenie:

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

będzie działać w ten sam sposób, ponieważ PSCustomObject jest "alias" dla pełnej przestrzeni nazw + nazwa klasy. Zamiast tego pojawia się błąd:

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

I wymienione akceleratory dla obu typów obiektów:

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

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

i odkrył, że zarówno odnosić się do tego samego PSObject klasy - ma to oznaczać, że za pomocą akceleratorów można zrobić kilka innych rzeczy niż tylko skrócenie kodu.

Moje pytania dotyczące tej kwestii są:

  1. Czy masz jakieś ciekawe examaples różnic pomiędzy użyciem akceleratora vs użyciu pełnej nazwy typu?
  2. Czy należy unikać używania pełnej nazwy typu, gdy akcelerator jest dostępny jako najlepsza ogólna praktyka?
  3. Jak sprawdzić, może za pomocą odbicia, czy akcelerator robi coś innego niż wskazywanie na podstawową klasę?
+4

Jeśli dekompilujesz 'System.Management.Automation.Language.Compiler.VisitConvertExpression', można zauważyć, że istnieje specjalna obsługa trzech nazw typów: 'zamówione',' PSCustomObject' i 'ref'. – PetSerAl

Odpowiedz

5

Patrząc na metody statyczne:

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

typu akcelerator ma kilka nowych metod statycznych dodał. Podejrzewam, że używa jednego z nich jako konstruktora.

2

[PSObject] i [PSCustomObject] to aliasy tego samego typu - System.Management.Automation.PSObject. Nie mogę powiedzieć, że istnieje ku temu dobry powód, ale przynajmniej sugeruje to dwa różne cele i może to wystarczający powód.

System.Management.Automation.PSObject służy do zawijania obiektów. Został wprowadzony w celu zapewnienia wspólnego interfejsu API do refleksów nad dowolnym obiektem, który obejmuje PowerShell - .Net, WMI, COM, ADSI lub prostymi torbami właściwości.

System.Management.Automation.PSCustomObject to tylko szczegół implementacji. Podczas tworzenia obiektu PSObject obiekt PSObject musi zawinąć coś. W przypadku toreb z materiałami opakowanym obiektem jest System.Management.Automation.PSCustomObject.SelfInstance (element wewnętrzny). Ta instancja jest ukryta przed normalnym użyciem PowerShella, jedynym sposobem na jej obserwację jest odbicie.

torby nieruchomości są tworzone na wiele sposobów w PowerShell:

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

Zarówno $ o1 i o2 $ powyżej będzie instancją PSObject i PSObject zawinie PSCustomObject.SelfInstance. PSCustomObject.SelfInstance jest używana wewnętrznie w PowerShell, aby odróżnić prosty worek właściwości od zawijania dowolnego innego obiektu.

+0

Witam Jason. Zarówno 'Get-Member' jak i' .GetType() 'zgłaszają zarówno $ o1 jak i $ o2 jako instancje PSCustomObject zamiast PSObject. –

+0

Jeśli jednak utworzę trzeci obiekt jako '$ o3 = [psobject] @ {Prop1 = 42}', ten obiekt jest inny. –

+1

Moim celem jest to, że powyższa odpowiedź jest myląca, ponieważ w powershell '[psobject]' i '[pscustomobject]' z pewnością nie działają tak samo. –