powershell - 如何将 System.Collections.ArrayList 添加到 PowerShell 自定义对象?

标签 powershell arraylist pscustomobject

我的目标是创建一个自定义数据对象,它具有两个离散变量( fooNamefooUrl )和一个 fooChildren 列表。 ,每个列表项有两个离散变量变量 childAgechildName .

目前,我有这个:

$fooCollection = [PSCustomObject] @{fooName=""; fooUrl=""; fooChildrenList=@()} 

$fooCollection.fooName = "foo-a-rama"
$fooCollection.fooUrl = "https://1.2.3.4"

$fooChild = New-Object -TypeName PSobject
$fooChild | Add-Member -Name childAge -MemberType NoteProperty -Value 6
$fooChild | Add-Member -Name childName -MemberType NoteProperty -Value "Betsy"
$fooCollection.fooChildrenList += $fooChild

$fooChild = New-Object -TypeName PSobject
$fooChild | Add-Member -Name childAge -MemberType NoteProperty -Value 10
$fooChild | Add-Member -Name childName -MemberType NoteProperty -Value "Rolf"
$fooCollection.fooChildrenList += $fooChild

cls
$fooCollection.fooName
$fooCollection.fooUrl

foreach ($fooChild in $fooCollection.fooChildrenList)
{
    ("  " + $fooChild.childName + " " + $fooChild.childAge)
}

这会产生以下结果。到目前为止一切顺利

foo-a-rama
https://1.2.3.4
  Betsy 6
  Rolf 10

问题:我不喜欢使用 +=因为据我了解,使用 +=结果是 $fooCollection.fooChildrenList 的副本每次都被创建(无论它处于什么状态)+=已执行。

所以,不要实现 fooChildrenList@() ,我想实现fooChildrenListNew-Object System.Collections.ArrayList所以我可以根据需要添加每一行。我已经尝试过在代码中执行此操作的各种方法,但是 fooChildrenList最终无人居住。例如:

$fooCollection = [PSCustomObject] @{fooName=""; fooUrl=""; fooChildrenList = New-Object System.Collections.ArrayList} 

$fooCollection.fooName = "foo-a-rama"
$fooCollection.fooUrl = "https://1.2.3.4"

$fooChild.childName = "Betsy"
$fooChild.childAge = 6
$fooCollection.fooChildrenList.Add((New-Object PSObject -Property $fooChild))

$fooChild.childName = "Rolf"
$fooChild.childAge = 10
$fooCollection.fooChildrenList.Add((New-Object PSObject -Property $fooChild))

$fooCollection | get-member显示

TypeName: System.Management.Automation.PSCustomObject

Name            MemberType   Definition                                   
----            ----------   ----------                                   
Equals          Method       bool Equals(System.Object obj)               
GetHashCode     Method       int GetHashCode()                            
GetType         Method       type GetType()                               
ToString        Method       string ToString()                            
fooChildrenList NoteProperty System.Collections.ArrayList fooChildrenList=
fooName         NoteProperty string fooName=foo-a-rama                    
fooUrl          NoteProperty string fooUrl=https://1.2.3.4  

$fooCollection显示

fooName         : foo-a-rama
fooUrl          : https://1.2.3.4
fooChildrenList : {} 

如何将 System.Collections.ArrayList 添加到 PowerShell 自定义对象?

最佳答案

挑战是添加您重新创建的 $fooChild [pscustomobject] 实例的副本。每次使用 .Add() 添加到列表时使用(如果不使用副本,最终会得到所有指向该列表的元素) 相同对象)。

但是,您无法使用 New-Object PSObject -Property 克隆现有的 [pscustomobject](又名 [psobject])实例>

一个选项 (PSv3+) 是将可重用的 $fooChild 定义为有序哈希表,然后使用 [pscustomobject] cast,每次都会隐式创建一个新对象:

$fooCollection = [PSCustomObject] @{ fooChildrenList = New-Object Collections.ArrayList } 

# Create the reusable $fooChild as an *ordered hashtable* (PSv3+)
$fooChild = [ordered] @{ childName = ''; childAge = -1 }

# Create 1st child and add to list with [pscustomobject] cast
$fooChild.childName = 'Betsy'; $fooChild.childAge = 6
$null = $fooCollection.fooChildrenList.Add([pscustomobject] $fooChild)

# Create and add another child.
$fooChild.childName = 'Rolf'; $fooChild.childAge = 10
$null = $fooCollection.fooChildrenList.Add([pscustomobject] $fooChild)

# Output the children
$fooCollection.fooChildrenList

请注意 $null = ...,它会抑制 .Add() 方法调用中通常不需要的输出。

以上产量:

childName childAge
--------- --------
Betsy            6
Rolf            10

一个稍微晦涩的替代方案是坚持使用$fooChild作为[pscustomobject]实例并调用。 psobject.Copy() 来创建一个克隆。


ArcSet's helpful answer提供了更加模块化的解决方案,可以通过帮助函数按需创建新的自定义对象实例。


最后,在PSv5+中,您可以定义一个助手:

$fooCollection = [PSCustomObject] @{ fooChildrenList = New-Object Collections.ArrayList } 

# Define helper class
class FooChild {
  [string] $childName
  [int]    $childAge
}

# Create 1st child and add to list with [pscustomobject] cast
$null = $fooCollection.fooChildrenList.Add([FooChild] @{ childName = 'Betsy'; childAge = 6 })

# Create and add another child.
$null = $fooCollection.fooChildrenList.Add([FooChild] @{ childName = 'Rolf'; childAge = 10 })

# Output the children
$fooCollection.fooChildrenList

请注意如何通过简单地转换具有与类属性名称匹配的条目的哈希表来创建 [FooChild] 的实例。

关于powershell - 如何将 System.Collections.ArrayList 添加到 PowerShell 自定义对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52336315/

相关文章:

java - 谁能告诉我为什么我的更改数量按钮没有更改数量?

java - 哪个更快?双 [][] 矩阵或 ArrayList<ArrayList<Double>>

powershell - PSCustomObject 是否有其显示到控制台的顺序?

powershell - 将pscustomobject传递到Start-Job脚本 block 时,为什么脚本属性丢失?

从批处理文件启动时的 PowerShell 窗口

powershell - 如何启动一个进程,暂停 2 小时,然后在 Powershell 中终止一个进程

java - 从列表中获取随机字符串

PowerShell WebRequest POST

parsing - 在 PowerShell 语法中, `lvalueExpression` 规则说的是什么?