如何将 System.Collections.ArrayList 添加到 PowerShell 自定义对象?
How do I add a System.Collections.ArrayList to a PowerShell custom object?
我的目标是创建一个自定义数据对象,它有两个离散变量(fooName
和 fooUrl
)和一个 fooChildren
列表,每个列表项都有两个离散变量变量childAge
和 childName
.
目前,我有这个:
$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
实现为 @()
,而是将 fooChildrenList
实现为 New-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 自定义对象?
从我用来制作一些数组的东西中快速复制粘贴。我必须创建自定义对象,然后将它们添加到数组中。它需要根据您的情况进行修改,但我认为它会满足您的需求。
[System.Collections.ArrayList]$SQL_Query_Results = @()
ForEach ($SQL_Index in $SQL_Table) {
$SQL_Array_Object = [PSCustomObject]@{
'Computer_Name' = $SQL_Table[$SQL_Index_Counter].ComputerID -replace ",", ""
'Project' = $SQL_Table[$SQL_Index_Counter].Project
'Site' = $SQL_Table[$SQL_Index_Counter].Site
'Description' = $SQL_Table[$SQL_Index_Counter].Description -replace ",", ""
'Physical_Machine' = $SQL_Table[$SQL_Index_Counter].IsPhysicalMachine
'Active' = $SQL_Table[$SQL_Index_Counter].IsActive
}
$SQL_Query_Results.Add($SQL_Array_Object) | Out-Null
}
经过编辑以显示 Array 最初是如何创建的。
嗯,我不确定你遇到了什么问题,它对我来说很好
function New-Child([string]$Name, [int]$Age){
$Child = New-Object -TypeName PSobject
$Child | Add-Member -Name childAge -MemberType NoteProperty -Value $age -PassThru |
Add-Member -Name childName -MemberType NoteProperty -Value $name
return $child
}
$fooCollection = [PSCustomObject] @{fooName=""; fooUrl=""; fooChildrenList = New-Object System.Collections.ArrayList}
$fooCollection.fooName = "foo-a-rama"
$fooCollection.fooUrl = "https://1.2.3.4"
$fooCollection.fooChildrenList.Add((New-Child -Name "Betty" -Age 9)) | Out-Null
$fooCollection.fooChildrenList.Add((New-Child -Name "Ralf" -Age 15)) | Out-Null
$fooCollection.fooName
$fooCollection.fooUrl
foreach ($fooChild in $fooCollection.fooChildrenList)
{
" " + $fooChild.childName + " " + $fooChild.childAge
}
输出
foo-a-rama
https://1.2.3.4
Betty 9
Ralf 15
挑战是添加一个副本 $fooChild
[pscustomobject]
实例,你重新- using 每次用 .Add()
添加到列表 时(如果不使用副本,最终所有列表元素都指向 相同对象)。
但是,您不能使用 New-Object PSObject -Property
.[=28 克隆现有的 [pscustomobject]
(a.k.a [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()
在上面创建一个克隆。
提供了一个更加模块化的解决方案, 通过 辅助函数 根据需要创建新的自定义对象实例。 =28=]
最后,在 PSv5+ 中,您可以 定义一个助手 class:
$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
请注意如何通过简单地转换具有与 class 属性 名称匹配的条目的哈希表来创建 [FooChild]
的实例。
我的目标是创建一个自定义数据对象,它有两个离散变量(fooName
和 fooUrl
)和一个 fooChildren
列表,每个列表项都有两个离散变量变量childAge
和 childName
.
目前,我有这个:
$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
实现为 @()
,而是将 fooChildrenList
实现为 New-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 自定义对象?
从我用来制作一些数组的东西中快速复制粘贴。我必须创建自定义对象,然后将它们添加到数组中。它需要根据您的情况进行修改,但我认为它会满足您的需求。
[System.Collections.ArrayList]$SQL_Query_Results = @()
ForEach ($SQL_Index in $SQL_Table) {
$SQL_Array_Object = [PSCustomObject]@{
'Computer_Name' = $SQL_Table[$SQL_Index_Counter].ComputerID -replace ",", ""
'Project' = $SQL_Table[$SQL_Index_Counter].Project
'Site' = $SQL_Table[$SQL_Index_Counter].Site
'Description' = $SQL_Table[$SQL_Index_Counter].Description -replace ",", ""
'Physical_Machine' = $SQL_Table[$SQL_Index_Counter].IsPhysicalMachine
'Active' = $SQL_Table[$SQL_Index_Counter].IsActive
}
$SQL_Query_Results.Add($SQL_Array_Object) | Out-Null
}
经过编辑以显示 Array 最初是如何创建的。
嗯,我不确定你遇到了什么问题,它对我来说很好
function New-Child([string]$Name, [int]$Age){
$Child = New-Object -TypeName PSobject
$Child | Add-Member -Name childAge -MemberType NoteProperty -Value $age -PassThru |
Add-Member -Name childName -MemberType NoteProperty -Value $name
return $child
}
$fooCollection = [PSCustomObject] @{fooName=""; fooUrl=""; fooChildrenList = New-Object System.Collections.ArrayList}
$fooCollection.fooName = "foo-a-rama"
$fooCollection.fooUrl = "https://1.2.3.4"
$fooCollection.fooChildrenList.Add((New-Child -Name "Betty" -Age 9)) | Out-Null
$fooCollection.fooChildrenList.Add((New-Child -Name "Ralf" -Age 15)) | Out-Null
$fooCollection.fooName
$fooCollection.fooUrl
foreach ($fooChild in $fooCollection.fooChildrenList)
{
" " + $fooChild.childName + " " + $fooChild.childAge
}
输出
foo-a-rama
https://1.2.3.4
Betty 9
Ralf 15
挑战是添加一个副本 $fooChild
[pscustomobject]
实例,你重新- using 每次用 .Add()
添加到列表 时(如果不使用副本,最终所有列表元素都指向 相同对象)。
但是,您不能使用 New-Object PSObject -Property
.[=28 克隆现有的 [pscustomobject]
(a.k.a [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()
在上面创建一个克隆。
最后,在 PSv5+ 中,您可以 定义一个助手 class: 请注意如何通过简单地转换具有与 class 属性 名称匹配的条目的哈希表来创建
$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]
的实例。