🐕

PowerShell用のディープコピー

に公開

おっさんさ、もーウンザリなんだよメンバ毎に手動コピーとかよ
.Net様みたくシリアライズでどーにかなれよッ
つーわけで思いつく範囲のメンド臭そーなコピーをどーにかすることにする
とりあえず配列とハッシュとPSCustomObjectとクラス、お前らだわ

本題

実はクラスの場合、コピー元クラスのプロパティを扱うのでメンバ変数定義だけじゃ駄目です
Add-Type -TypeDefinitionでC#のクラス定義を生成した場合は注意が必要

function DeepCopyObj {
    param (
        [Parameter(Mandatory = $true)] [object] $Data
    )
    begin {}
    process {
        if ($null -eq $Data) {
            return $null
        } elseif ($Data.GetType().IsPrimitive) {
            return $Data
        } elseif ($Data -is [string] -or $Data -is [datetime] -or $Data -is [decimal]) {
            return $Data
        } elseif ($Data -is [hashtable]) {
            $inst = @{}
            foreach ($key in $Data.Keys) {
                $inst[$key] = DeepCopyObj $Data[$key]
            }
            return $inst
        } elseif ($Data -is [array]) {
            $inst = @()
            foreach ($item in $Data) {
                $inst += DeepCopyObj $item
            }
            return $inst
        } elseif ($Data -is [System.Management.Automation.PSCustomObject]) {
            $inst = [PSCustomObject]@{}
            foreach ($prop in $Data.PSObject.Properties) {
                $inst | Add-Member -MemberType NoteProperty -Name $prop.Name -Value (DeepCopyObj $prop.Value)
            }
            return $inst
        } elseif ($Data.GetType().IsClass -and -not $Data.GetType().IsValueType) {
            $type = $Data.GetType()
            $inst = New-Object -TypeName $type.FullName
            foreach ($prop in $type.GetProperties()){
                if ($prop.CanRead -and $prop.CanWrite) {
                    $prop.SetValue($inst, $prop.GetValue($Data))
                }
            }
            return $inst
        } else {
            return $Data
        }
    }
    end {}
}

え?パフォーマンス?
そんなもの考えてたら普通に.Netで書くでしょ?

Discussion