about_PSCustomObject

Breve descrizione

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

Descrizione lunga

L'acceleratore [pscustomobject] di tipi è 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, è stato necessario usare New-Object per creare l'oggetto e Add-Member per aggiungere proprietà. Ad 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

In un secondo momento, è possibile usare il parametro Property di New-Object per passare una tabella Hash contenente i membri e i valori. Ad 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, eseguire il cast di una tabella Hash per [pscustomobject] ottenere 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 gli oggetti Hashtable non garantiscono l'ordine delle coppie chiave-valore, eseguire il cast di una tabella hash letterale per [pscustomobject] mantenere 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
PSVersion Name     System
--------- ----     ------
4.0       Server30 Server Core

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] sia necessario 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 [pscustomobject] di tipi è stato aggiunto a PowerShell, include codice aggiuntivo per gestire la conversione di una tabella Hash in un tipo PSObject . Questo codice aggiuntivo viene richiamato solo quando viene creato un nuovo oggetto. Pertanto, non è possibile usare [pscustomobject] per la coercizione dei tipi o per il confronto dei tipi, perché tutti gli oggetti vengono considerati come tipi PSObject .

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

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

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

Quando si esegue il cast di qualsiasi oggetto per [psobject] ottenere il tipo dell'oggetto originale. Pertanto, eseguire il cast di elementi diversi da una tabella Hash per ottenere [pscustomobject] 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

Mentre 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 [psobject] tipo.

    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 di cui è stato eseguito il 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 a , [pscustomobject]PowerShell mantiene tale maiuscole/minuscole delle chiavi, 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:

$OrderedHashTable = [System.Collections.Specialized.OrderedDictionary]::new()
$OrderedHashTable['One'] = 1
$OrderedHashTable['TWO'] = 2
$OrderedHashTable['two'] = 3  # case variation
$OrderedHashTable['Three'] = 3
$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

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

[pscustomobject]$OrderedHashTable
One TWO Three
--- --- -----
  1   3     3

Note

In Windows PowerShell gli oggetti creati eseguendo il cast di una tabella Hash per non hanno le [pscustomobject] o Count. Il tentativo di accedere a questi membri restituisce $null.

Ad 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 una tabella Hash per avere sempre un valore per [pscustomobject] le 1 e Count.

Vedere anche