Dot-Net
深拷貝 PSObject
我有一個 powershell 腳本,我在其中執行以下操作
$somePSObjectHashtables = New-Object Hashtable[] $somePSObject.Length; $somePSObjects = Import-CSV $csvPath 0..($somePSObject.Length - 1) | ForEach-Object { $i = $_; $somePSObjectHashtables[$i] = @{}; $somePSObject[$_].PSObject.Properties | ForEach-Object { $somePSObjectHashtables[$i][$_.Name] = $_.Value; } }我需要這樣做,因為我想在 CSV 中製作幾個不同的數據副本以執行幾個不同的操作。從某種意義上說,我正在對PSObject的結果數組執行“INNER JOIN” 。
$somePSObjectHashtables我可以輕鬆地使用ForEach-Object迭代並在數組的每個成員上呼叫Hashtable.Clone() 。然後我可以New-Object PSObject -Property $someHashTable[$i]用來獲取 PSObject 的深層副本。我的問題是,是否有一些更簡單的方法來製作深層副本,而無需中間雜湊表?
為了獲得真正的深度副本,我們可以使用二進制序列化(假設所有數據都是可序列化的;對於來自 CSV 的數據肯定是這種情況):
# 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
請注意,這是一個更短,也許更簡潔的版本(我很喜歡):
$data = Import-Csv .\test.csv $serialData = [System.Management.Automation.PSSerializer]::Serialize($data) $data2 = [System.Management.Automation.PSSerializer]::Deserialize($serialData)注意:然而,奇怪的是,它不保持有序雜湊表的順序。
$data = [ordered] @{ 1 = 1 2 = 2 } $serialData = [System.Management.Automation.PSSerializer]::Serialize($data) $data2 = [System.Management.Automation.PSSerializer]::Deserialize($serialData) $data2將輸出:
Name Value ---- ----- 2 2 1 1而對於其他類型,它工作得很好:
$data = [PsCustomObject] @{ 1 = 1 2 = 2 } $data = @(1, 2, 3)