2012-03-06 6 views
12

Я хочу создать новый экземпляр моего пользовательского объекта PSObject. У меня есть объект Button, созданный как PSObject, и я хочу создать новый объект Button2, который имеет те же элементы, что и Button, но я не могу найти способ клонирования исходного объекта, не ссылаясь на исходный объект (если я изменяю свойство в Button2 также изменяется в Button). Есть ли способ сделать это так же, как с hashtables и массивами с помощью некоторого метода Clone()?Как создать новый экземпляр clone объекта PSObject

+0

Перейти на мой ответ, если вы хотите функцию 'clone', чтобы сделать это для вас –

ответ

9

Действительно, нет метода клонирования! Однако там, где есть воля ...

$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 

Выход:

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

это странно, я не метод Clone availabl е. Похоже, есть проблема в том, как я разбиваю объект. Когда я использую ваш пример, у меня есть метод Clone, но я сначала создаю пустой объект, а затем добавляю всех участников через Add-Member. Поэтому, когда я использую: $ object = New-Object PSObject $ object | Add-Member NoteProperty propVal "test" powershell говорит, что [System.Management.Automation.PSCustomObject] не содержит метода Close. –

+0

@JosefNemec Плохо я использовал неправильный синтаксис для создания PsObject. Вы правы, что нет метода клонирования. Поэтому, чтобы обойти это, вы можете просто скопировать все свойства оригиналов в новый объект. –

+0

Отлично работает, спасибо! –

11

Другая возможность:

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

Кажется, не работает ... Я получил новое значение для обоих. Попробуйте вызвать 'GetHashCode()', они указывают на один и тот же объект для меня. –

+0

Вы правы. Плохое тестирование. Я сниму это. – mjolinor

+0

Различные методы. Работает лучше. – mjolinor

45

Самый простой способ заключается в использовании Copy методом 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 

Выход:

Fld3 : Fld3 
Fld2 : Fld2 
Fld1 : Fld1 

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

По какой-то причине PSObject.Copy() не работает для всех типов объектов. Другое решение, чтобы создать копию объекта, чтобы преобразовать его в/из Json затем сохранить его в новой переменной:

$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

Это единственный ответ до сих пор, который будет глубоко клонировать psobject, который содержит другие psobjects. – aggieNick02

0

Put это в классе Utility или определить его в текущем разделе

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

Использование:

$clonedobj = clone $obj

Смежные вопросы