2012-03-06 27 views
12

Quiero crear una nueva instancia de mi PSObject personalizado. Tengo un objeto Button creado como PSObject y quiero crear un nuevo objeto Button2 que tiene los mismos miembros que Button, pero no puedo encontrar la forma de clonar el objeto original sin hacerlo referenciarlo en el objeto original (si cambio una propiedad en Button2 también cambia en Button). ¿Hay alguna manera de hacerlo de manera similar a las tablas y tablas hash a través de algún método Clone()?Cómo crear una nueva instancia de clonación del objeto PSObject

+0

Ir a mi respuesta si desea una función 'clone' a hacer esto para usted –

Respuesta

9

De hecho, no existe un método de clonación. Sin embargo, donde hay una voluntad ...

$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 

Salida:

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

Eso es raro, no tengo método Clone availabl mi. Parece que hay un problema en la forma en que marco el objeto. Cuando uso su ejemplo, tengo el método Clone disponible, pero primero creo el objeto vacío y luego agrego todos los miembros a través de Add-Member. Entonces cuando uso: $ object = New-Object PSObject $ object | Add-Member NoteProperty propVal "test" powershell dice que [System.Management.Automation.PSCustomObject] no contiene el método Close. –

+0

@JosefNemec Mi mal que utilicé la sintaxis incorrecta para crear PsObject. Tiene razón en que no hay un método de clonación. Entonces, para solucionarlo, puede copiar todas las propiedades de los originales al nuevo objeto. –

+0

Funciona muy bien, muchas gracias! –

11

Otra posibilidad:

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

Parece que no funciona ... Tengo un valor nuevo para ambos. Intenta llamar a 'GetHashCode()', ellos apuntan al mismo objeto para mí. –

+0

Tienes razón. Malas pruebas Voy a retirar eso. – mjolinor

+0

Método diferente. Funciona mejor – mjolinor

45

La manera más fácil es utilizar el método Copy de un 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 

Salida:

Fld3 : Fld3 
Fld2 : Fld2 
Fld1 : Fld1 

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

Por alguna razón PSObject.Copy() no funciona para todos los tipos de objetos. Otra solución para crear una copia de un objeto es convertir a/desde JSON a continuación, guardarlo en una nueva variable:

$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

Esta es la única respuesta hasta el momento que clonará un psobject que contiene otros psobjects. – aggieNick02

0

Pon esto en una clase de utilidad o definirlo en su sección actual

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

Cuestiones relacionadas