gpt4 book ai didi

powershell - powershell函数返回用户定义类的实例将导致构造函数返回另一个新实例

转载 作者:行者123 更新时间:2023-12-02 23:51:04 27 4
gpt4 key购买 nike

环境信息:

PS C:\> Get-WmiObject Win32_OperatingSystem


SystemDirectory : C:\Windows\system32
Organization :
BuildNumber : 9600
RegisteredUser : xxxxxxxxxxxxxxxxxxxxxxx
SerialNumber : xxxxx-xxxxx-xxxxx-xxxxx
Version : 6.3.9600 # Windows 8.1, Update 1



PS C:\> $PSVersionTable

Name Value
---- -----
PSVersion 5.1.14409.1018
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1018
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

背景:

为什么我这样做:
  • 我的USB硬盘有点不稳定。并且我需要查找文件并逐步存储路径。
  • 如果将发生某些错误,请存储错误信息而不是路径。
  • 我打算使用[TreeElement]对象进行存储和搜索。

  • 我做了一个简单的树类:

    # need Powershell v5.0 higher
    class TreeElement
    {
    $Value = $null
    [System.Collections.Generic.List[TreeElement]] $Children = [System.Collections.Generic.List[TreeElement]]::new()
    [TreeElement] $Parent = $null

    TreeElement($Value)
    {
    $this.Value = $Value
    }

    [TreeElement] AddChild([TreeElement] $Child)
    {
    $this.Children.Add($Child)
    return $Child
    }

    [TreeElement] AddChildValue($ChildValue)
    {
    $Child = [TreeElement]::new($ChildValue)
    $this.Children.Add($Child)
    return $Child
    }
    }

    我完成了编码,并进行了如下测试:

    $root = [TreeElement]::new(1)
    $root.AddChildValue(2)
    $root.AddChildValue(3)
    $root.AddChildValue(4)
    $root.AddChildValue(5)

    $root

    最后一行将在控制台中显示此内容。

    Value Children                                             Parent
    ----- -------- ------
    1 {TreeElement, TreeElement, TreeElement, TreeElement}



    我想将 $root存储到文件中。

    所以我决定使用 *-Clixml,并进行编码:

    Function Store-Tree
    {
    [OutputType([void])]
    Param
    (
    [string]$Path,
    [TreeElement]$RootElement
    )

    Export-Clixml -Path $Path -InputObject $RootElement
    }

    Function Restore-Tree
    {
    Param
    (
    [string]$Path
    )

    # restore from xml
    $obj = Import-Clixml -Path $Path

    # Reconstruct instances...
    $result = Reconstruct-Tree -RootObject $obj
    return $result
    }

    Function Reconstruct-Tree
    {
    [OutputType([TreeElement])]
    Param
    (
    [PSObject] $RootObject
    )

    $root = [TreeElement]::new($RootObject.Value)

    foreach($ChildObject in $RootObject.Children)
    {
    [TreeElement] $branch = Reconstruct-Tree $ChildObject
    [void] $root.AddChild($branch)
    }

    return $root
    }

    然后我测试了它:

    PS> mkdir C:\temp
    PS> $path = "C:\temp\root-tree.xml"
    PS> $root # original instance

    Value Children Parent
    ----- -------- ------
    1 {TreeElement, TreeElement, TreeElement, TreeElement}


    PS> Store-Tree -Path $path -RootElement $root # store in xml. instances are converted to [PsObject] internally.
    PS> $root_r = Restore-Tree -Path $path # restore instances with type of [TreeElement].

    Value Children Parent
    ----- -------- ------
    TreeElement {} # what?


    问题:

    我期望 $root_r的实例与 $root几乎相同。

    但是 $root_r在Children成员中具有预期的对象。

    我只想归还对象。

    调试显示,当 [TreeElement]函数返回对象时, Reconstruct-Tree构造函数正在运行。

    题:

    有没有办法只返回对象?我做错什么了吗?

    我在某个网站上进行了搜索,但未获得任何信息。

    任何帮助表示赞赏。

    提前谢谢你的帮助。

    最佳答案

    自我解决。

    调试步骤1:

  • 首先粘贴代码[A]和[S]。
  • 然后用[T]测试。
  • 没什么奇怪的。

  • 调试步骤2:
  • 首先粘贴代码[A]和[S]。
  • 然后,我像[A Modifyed]一样修改了[TreeElement]类。
  • 粘贴代码[已修改]。
  • 然后,用[T]进行测试。
  • 发生了一些奇怪的事情。

  • 为什么?
  • (1)当我运行'[Amodified]'时,它将修复[TreeElement]本身的定义。
  • (2)但是函数Reconstruct-Tree中的' [TreeElement] '的定义是,不固定
  • (3)因此(1)的[TreeElement]与(2)的' [TreeElement] 是不同的类型。
  • (4)然后Reconstruct-Tree尝试返回具有旧[TreeElement]类型(' [TreeElement] ')的[TreeElment]实例。
  • (5)和powershell决定实例是' [TreeElement] 的构造函数的参数。

  • 对不起,打扰你。
    谢谢。

    样例代码:
    [A]:[TreeElement]类的定义。
    # need Powershell v5.0 higher
    class TreeElement
    {
    $Value = $null
    [System.Collections.Generic.List[TreeElement]] $Children = [System.Collections.Generic.List[TreeElement]]::new()
    [TreeElement] $Parent = $null

    TreeElement($Value)
    {
    $this.Value = $Value
    }

    [TreeElement] AddChild([TreeElement] $Child)
    {
    $this.Children.Add($Child)
    return $Child
    }

    [TreeElement] AddChildValue($ChildValue)
    {
    $Child = [TreeElement]::new($ChildValue)
    $this.Children.Add($Child)
    return $Child
    }
    }
    [修改]:[TreeElement]类的新定义。
    class TreeElement
    {
    $Value = $null
    [System.Collections.Generic.List[TreeElement]] $Children = [System.Collections.Generic.List[TreeElement]]::new()
    [TreeElement] $Parent = $null
    [string] $Dummy = "editted class type!"

    TreeElement($Value)
    {
    $this.Value = $Value
    }

    [TreeElement] AddChild([TreeElement] $Child)
    {
    $this.Children.Add($Child)
    return $Child
    }

    [TreeElement] AddChildValue($ChildValue)
    {
    $Child = [TreeElement]::new($ChildValue)
    $this.Children.Add($Child)
    return $Child
    }
    }
    [S]:存储类的实例([TreeElement])。
    Function Store-Tree
    {
    [OutputType([void])]
    Param
    (
    [string]$Path,
    [TreeElement]$RootElement
    )

    Export-Clixml -Path $Path -InputObject $RootElement
    }

    Function Restore-Tree
    {
    Param
    (
    [string]$Path
    )

    # restore from xml
    $obj = Import-Clixml -Path $Path

    # Reconstruct instances...
    $result = Reconstruct-Tree -RootObject $obj
    return $result
    }

    Function Reconstruct-Tree
    {
    [OutputType([TreeElement])]
    Param
    (
    [PSObject] $RootObject
    )

    $root = [TreeElement]::new($RootObject.Value)

    foreach($ChildObject in $RootObject.Children)
    {
    [TreeElement] $branch = Reconstruct-Tree $ChildObject
    [void] $root.AddChild($branch)
    }

    return $root
    }
    [T]:测试代码。
    $path = "C:\temp\root-tree.xml"

    $root = [TreeElement]::new(1)
    $root.AddChildValue(2)
    $root.AddChildValue(3)
    $root.AddChildValue(4)
    $root.AddChildValue(5)

    $root # original instance

    Store-Tree -Path $path -RootElement $root # store in xml. instances are converted to [PsObject] internally.

    $root_r = Restore-Tree -Path $path # restore instances with type of [TreeElement].
    $root_r

    关于powershell - powershell函数返回用户定义类的实例将导致构造函数返回另一个新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59418711/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com