Клонирование объекта Powershell 3 дает неожиданные результаты — влияет на другой объект

У меня проблема с образцом кода, который я пишу. Это немного простой вопрос, но это проблема, которая заняла некоторое время, которого у меня нет. Я уже пробовал соответствующие вопросы и поиск в stackoverflow, но не нашел ничего, что очень помогло бы.

У меня есть следующий код:

#Importing some file from a csv to a variable
$output = import-csv -LiteralPath ...some file imports OK

##
#Copy the layout of the csv imported for further processing..
##
$extraOut = $output.clone() 
$extraOut | ForEach-Object {
$_.innerlinks1 = ""
$_.innerlinksurl1 = ""
}

Когда я пытаюсь распечатать значение $output, используя $_, я получаю пустые строки, которые я ранее назначил (чего я не хочу). Почему это происходит?

#Trying to print out $output should have data and not empty strings.
$output | ForEach-Object { Write-Host $_ }

Любая помощь или код, который позволяет копировать структуру результата Import-csv (с клонированием PSObject или без него), также будут отличными.

ПРИМЕЧАНИЕ. Найдя полезный ответ, я также думаю, что проблема требует более подробного сценария, поскольку в моем файле много пустых строк, которые могут вызвать дополнительные проблемы в будущем.


person Hskdopi    schedule 23.06.2017    source источник
comment
Метод clone массива выполняет поверхностное копирование, он не клонирует элементы. Поищите примеры правильного (глубокого) клонирования, их много.   -  person wOxxOm    schedule 23.06.2017
comment
Я пытался использовать .PSObject.copy(), но получил те же результаты. Я уже этим занимаюсь.   -  person Hskdopi    schedule 23.06.2017
comment
@MathiasR.Jessen Я пробовал это в ForEach-Object, но не сработало, как ожидалось. Да это массив объектов одного уровня вот так: @{name=;name2=} @{name=;name2=} etc..   -  person Hskdopi    schedule 23.06.2017


Ответы (1)


Я использую ответ в этой ссылке всякий раз, когда мне нужно глубоко скопировать массив. Чтобы процитировать оригинальный ответ:

# Get original data
$data = Import-Csv ...

# Serialize and Deserialize data using BinaryFormatter
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $data)
$ms.Position = 0
$data2 = $bf.Deserialize($ms)
$ms.Close()

# Use deep copied data
$data2
person Nick    schedule 23.06.2017
comment
Я считаю, что это самый близкий ответ на временный, который я уже нашел. - person Hskdopi; 23.06.2017
comment
После еще немного поиска я нашел еще пару связанных ответов на ваш, в этом ссылка и в GitHub как суть - person Hskdopi; 23.06.2017