about_PSCustomObject

Breve descrizione

Vengono illustrate le differenze tra gli acceleratori di tipo [psobject] e [pscustomobject].

Descrizione lunga

L'acceleratore di tipo [pscustomobject] è stato aggiunto in PowerShell 3.0.

Prima di aggiungere questo acceleratore di tipo, la creazione di un oggetto con proprietà membro e valori era più complessa. In origine, era necessario usare New-Object per creare l'oggetto e Add-Member per aggiungere proprietà. Per esempio:

PS> $object1 = New-Object -TypeName psobject
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name one -Value 1
PS> Add-Member -InputObject $object1 -MemberType NoteProperty -Name two -Value 2
PS> $object1 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object1

one two
--- ---
  1   2

Successivamente, è possibile usare il parametro proprietà di New-Object per passare un hashtable contenente i membri e i valori. Per esempio:

PS> $object2 = New-Object -TypeName psobject -Property @{one=1; two=2}
PS> $object2 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object2

one two
--- ---
  1   2

A partire da PowerShell 3.0, il cast di un hashtable per [pscustomobject] ottiene lo stesso risultato.

PS> $object3 = [pscustomobject]@{one=1; two=2}
PS> $object3 | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
one         NoteProperty int one=1
two         NoteProperty int two=2

PS> $object3

one two
--- ---
  1   2

gli oggetti tipo PSObject mantengono l'elenco dei membri nell'ordine in cui i membri sono stati aggiunti all'oggetto. Anche se oggetti Hashtable non garantiscono l'ordine delle coppie chiave-valore, il cast di una tabella hash letterale per [pscustomobject] mantiene l'ordine.

La tabella hash deve essere un valore letterale. Se si esegue il wrapping della tabella hash tra parentesi o se si esegue il cast di una variabile contenente una tabella hash, non è garantito che l'ordine venga mantenuto.

$hash = @{
    Name      = "Server30"
    System    = "Server Core"
    PSVersion = "4.0"
}
$Asset = [pscustomobject]$hash
$Asset
System      Name     PSVersion
------      ----     ---------
Server Core Server30 4.0

Informazioni sugli acceleratori di tipi

[psobject] e [pscustomobject] sono acceleratori di tipo.

Per altre informazioni, vedere about_Type_Accelerators.

Anche se si potrebbe pensare che [pscustomobject] deve eseguire il mapping a System.Management.Automation.PSCustomObject, i tipi sono diversi.

PS> [pscustomobject] -eq [System.Management.Automation.PSCustomObject]
False

Entrambi gli acceleratori di tipo vengono mappati alla stessa classe, PSObject:

PS> [pscustomobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

PS> [psobject]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

Quando l'acceleratore di tipo [pscustomobject] è stato aggiunto a PowerShell, include codice aggiuntivo per gestire la conversione di un Hashtable in un tipo di PSObject. Questo codice aggiuntivo viene richiamato solo quando viene creato un nuovo oggetto. Pertanto, non è possibile usare [pscustomobject] per il confronto tra tipi o tipi, perché tutti gli oggetti vengono considerati come tipi di PSObject.

Ad esempio, l'uso dell'operatore -is per verificare che un oggetto restituito da un cmdlet sia un [pscustomobject] equivale a confrontarlo con [psobject].

PS> (Get-Item /) -is [pscustomobject]
True

PS> (Get-Item /) -is [psobject]
True

Quando si esegue il cast di qualsiasi oggetto per [psobject] si ottiene il tipo dell'oggetto originale. Di conseguenza, il cast di qualsiasi elemento diverso da un Hashtable per [pscustomobject] restituisce lo stesso tipo.

PS> ([psobject]@{Property = 'Value'}).GetType().FullName
System.Collections.Hashtable

PS> ([pscustomobject]123).GetType().Name
Int32

PS> ([pscustomobject]@{Property = 'Value'}).GetType().FullName
System.Management.Automation.PSCustomObject

Anche se il cast di un oggetto a [psobject] sembra non avere alcun effetto sul tipo, PowerShell aggiunge un wrapper invisibile[psobject] intorno all'oggetto. Questo può avere effetti collaterali sottili.

  • Gli oggetti di cui è stato eseguito il wrapping corrispondono al tipo originale e al tipo di [psobject].

    PS> 1 -is [int32]
    True
    PS> 1 -is [psobject]
    False
    PS> ([psobject] 1) -is [int32]
    True
    PS> ([psobject] 1) -is [psobject]
    True
    
  • L'operatore format (-f) non riconosce una matrice sottoposta a wrapping da [psobject].

    PS> '{0} {1}' -f (1, 2)
    1 2
    PS> '{0} {1}' -f ([psobject] (1, 2))
    Error formatting a string: Index (zero based) must be greater than or equal
    to zero and less than the size of the argument list..
    

Conversione di tabelle hash contenenti chiavi simili

I dizionari con distinzione tra maiuscole e minuscole possono contenere nomi di chiave che differiscono solo per maiuscole e minuscole. Quando si esegue il cast di un dizionario di questo tipo in un [pscustomobject], PowerShell mantiene tale distinzione tra maiuscole e minuscole, ma non fa distinzione tra maiuscole e minuscole. Di conseguenza:

  • Il caso della prima chiave duplicata diventa il nome della chiave.
  • Il valore dell'ultima chiave di tipo case-variant diventa il valore della proprietà.

L'esempio seguente illustra questo comportamento:

$Json = '{
  "One": 1,
  "two": 2,
  "Two": 3,
  "three": 3,
  "Three": 4,
  "THREE": 5
}'
$OrderedHashTable = $Json | ConvertFrom-Json -AsHashTable
$OrderedHashTable

Si noti che la tabella hash ordinata contiene più chiavi che differiscono solo per caso.

Name                           Value
----                           -----
One                            1
two                            2
Two                            3
three                          3
Three                          4
THREE                          5

Quando viene eseguito il cast di tale tabella hash a un [pscustomobject], viene usato il caso del nome della prima chiave, ma viene usato il valore dell'ultimo nome della chiave corrispondente.

[pscustomobject]$OrderedHashTable
One two three
--- --- -----
  1   3     5

Note

In Windows PowerShell gli oggetti creati eseguendo il cast di un hashtable a [pscustomobject] non hanno le proprietà Length o Count Count. Il tentativo di accedere a questi membri restituisce $null.

Per esempio:

PS> $object = [pscustomobject]@{key = 'value'}
PS> $object

key
---
value

PS> $object.Count
PS> $object.Length

A partire da PowerShell 6, gli oggetti creati eseguendo il cast di un hashtable a [pscustomobject] hanno sempre un valore di 1 per le proprietà Length e Count .

Vedere anche