Powershell中类实例的问题

时间:2019-05-21 21:01:34

标签: powershell oop powershell-v4.0

我一直在Powershell中进行一个项目,该项目利用了语言的面向对象特性。

这就是我想要做的:

  1. 我创建了几个具有不同属性的类。我们可以将这些类之一称为“ ClassA”。

  2. 这些类的属性之一是另一个类。我们可以称其为“ ClassB”。

  3. 我为每个这些类创建了几个实例。

  4. 我需要设置类的参数,这是另一个类的参数。因此,例如:ClassAInstance.ClassBInstance.Property1

  5. 我正在使用类方法来更新这些参数。

我发现的是,当我设置这些最低级别的属性之一时,它将在先前存在的类的所有实例上更新该参数。

奇怪的是,ClassA实例(不是ClassB类型)的属性可以很好地更新,而不会影响任何现有的ClassA实例。问题仅在于ClassB实例的属性,即ClassA实例的属性。

知道为什么会这样吗?

我对缺乏细节深表歉意。这很困难,因为代码已经变得非常复杂,并且其中还包含很多专有信息。

Class XBlock
{
    [string]$Name
}

Class YBlock: XBlock
{
    [string]$Name = 'Y1'
    [float]$High_Scale = 100
}

Class XClass
{
    [string]$Name = ''
    [System.Collections.ArrayList]$CodeBlock

    SetXParams()
    {
        $blocknames = New-Object System.Collections.Arraylist

        for ($i = 1; $i -le $this.XBlocks; $i++)
        {
            $blocknames.add("X$i")
        }

        $blocknames | %{

            $this.$_ = New-Object XBlock

            $pattern = -join ('Attribute_Instance Name="', $_, '/High_Scale')
            $match = $this.CodeBlock | Select-String -Pattern $pattern -Context 0, 2 -ErrorAction SilentlyContinue
            If ($match.count -gt 0)
            {
                $this.$_.High_Scale = ($match[0].Context.PostContext[1]).split('=').split(' ')[7]
            }       

        }
    }   
}

class YClass: XClass
{
    [int]$YBlocks = 1
    [YBlock]$Y1
}

Class XModule
{
    [string]$Name = ''
    [string]$Class = ''
    [System.Collections.ArrayList]$CodeBlock
    [int]$XBlocks = 0

    [System.Collections.ArrayList]$CodeBlock

    SetModuleParams([XModule]$XModule)
    {
        $this.Name = $XModule.Name

        $this.CodeBlock = $XModule.CodeBlock

        $this.ClassObject = ($Global:AllClasses | ? { $_.Name -eq $this.Class }).PSObject.Copy()

    }

    SetYParams()
    {
        $blocknames = New-Object System.Collections.Arraylist


        for ($i = 1; $i -le $this.XBlocks; $i++)
        {
            $blocknames.add("Y$i")
        }

        $blocknames | %{

            $this.$_ = New-Object YBlock
            $this.$_ = $this.ClassObject.$_.PSObject.Copy()

            $pattern = -join ('(Attribute Instance Name="', $_, '.*High_Scale)')
            $match = $this.CodeBlock | Select-String -Pattern '(Attribute Instance Name=".*High_Scale)' -Context 0, 2 #-ErrorAction SilentlyContinue -SimpleMatch $true
            If ($match.count -gt 0)
            {
                $this.$_.High_Scale = ($match[0].Context.PostContext[1]).split('=').split(' ')[7]
            }

        }

    }

}

1 个答案:

答案 0 :(得分:1)

在面向对象的程序设计中,当您复制对象时,就像您在Y1 = ($this.ClassObject.Y1).PSObject.Copy()中所做的那样,实际上并没有复制该对象,而只是复制了该对象的引用(对象实际所在的内存地址)居住)。这就是为什么在更新看似新的“ Y”对象上的属性然后设置属性时,还更改了原始对象的属性的原因。它们都指向内存中的同一位置。