2012-03-06 12 views
12

Voglio creare una nuova istanza del mio PSObject personalizzato. Ho un oggetto Button creato come PSObject e voglio creare un nuovo oggetto Button2 che ha gli stessi membri di Button, ma non riesco a trovare un modo su come clonare l'oggetto originale senza farlo riferimento nell'oggetto originale (se cambio una proprietà in Button2 cambia anche in Button). C'è un modo come farlo in modo simile con hashtables e array tramite un metodo Clone()?Come creare una nuova istanza clone dell'oggetto PSObject

+0

Vai alla mia risposta, se si desidera una funzione 'clone' per fare questo per voi –

risposta

9

In effetti non esiste un metodo di clonazione! Tuttavia, se c'è la volontà ...

$o = New-Object PsObject -Property @{ prop1='a' ; prop2='b' } 
$o2 = New-Object PsObject 
$o.psobject.properties | % { 
    $o2 | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value 
} 
$o.prop1 = 'newvalue' 

$o 
$o2 

uscita:

prop2  prop1                 
-----  -----                 
b   newvalue                
b   a  
+0

che strano, non ho metodo Clone dispon e. Sembra che ci sia un problema nel modo in cui creo l'oggetto. Quando uso il tuo esempio, ho a disposizione il metodo Clone, ma prima creo l'oggetto vuoto e poi aggiungo tutti i membri tramite Add-Member. Quindi, quando utilizzo: $ oggetto = Nuovo oggetto PSObject $ oggetto | Add-Member NoteProperty propVal "test" powershell dice che [System.Management.Automation.PSCustomObject] non contiene il metodo Close. –

+0

@JosefNemec Il mio male Ho usato la sintassi sbagliata per creare PsObject. Hai ragione sul fatto che non esiste un metodo di clonazione. Quindi, per ovviare al problema, è sufficiente copiare tutte le proprietà originali nel nuovo oggetto. –

+0

Funziona alla grande, grazie mille! –

11

Altra possibilità:

$o1 = New-Object PsObject -Property @{ prop1='a' ; prop2='b' } 
$o2 = $o1 | select * 
$o2.prop1 = 'newvalue' 
$o1.prop1 
$o2.prop1 
a 
newvalue 
+0

Non sembra funzionare ... Ho ottenuto il valore nuovo per entrambi. Prova a chiamare 'GetHashCode()', stanno puntando allo stesso oggetto per me. –

+0

Hai ragione. Test negativi. Lo ritirerò. – mjolinor

+0

Metodo diverso. Funziona meglio. – mjolinor

45

Il modo più semplice è quello di utilizzare la Copy Metodo di PsObject ==>$o2 = $o1.PsObject.Copy()

$o1 = New-Object -TypeName PsObject -Property @{ 
    Fld1 = 'Fld1'; 
    Fld2 = 'Fld2'; 
    Fld3 = 'Fld3'} 

$o2 = $o1.PsObject.Copy() 

$o2 | Add-Member -MemberType NoteProperty -Name Fld4 -Value 'Fld4' 
$o2.Fld1 = 'Changed_Fld' 

$o1 | Format-List 
$o2 | Format-List 

uscita:

Fld3 : Fld3 
Fld2 : Fld2 
Fld1 : Fld1 

Fld3 : Fld3 
Fld2 : Fld2 
Fld1 : Changed_Fld 
Fld4 : Fld4 
3

Per qualche motivo PSObject.Copy() non funziona per tutti i tipi di oggetti. Un'altra soluzione per creare una copia di un oggetto è per convertirlo da/JSON quindi salvarlo in una nuova variabile:

$CustomObject1 = [pscustomobject]@{a=1; b=2; c=3; d=4} 
$CustomObject2 = $CustomObject1 | ConvertTo-Json -depth 100 | ConvertFrom-Json 
$CustomObject2 | add-Member -Name "e" -Value "5" -MemberType noteproperty 

$CustomObject1 | Format-List 
$CustomObject2 | Format-List 
+0

Questa è l'unica risposta finora che clonerà in profondità un oggetto che contiene altri psobject. – aggieNick02

0

Mettere questo in una classe di utilità o definire nella vostra sezione corrente

function clone($obj) 
{ 
    $newobj = New-Object PsObject 
    $obj.psobject.Properties | % {Add-Member -MemberType NoteProperty -InputObject $newobj -Name $_.Name -Value $_.Value} 
    return $newobj 
} 

Uso:

$clonedobj = clone $obj

Problemi correlati