Powershell - 如何使用 $List.convertAll() 或其他 C# 方法来克隆列表



假设我有一个列表:

$DeletedUsers = New-Object System.Collections.Generic.List[System.object]

因此,我可以轻松地在集合中添加和删除用户。

我希望能够将此列表传递给执行某些操作的函数,但不修改原始列表,并且它必须保持相同的通用列表类型。

convertAll()似乎完全按照我的意愿去做,而不必自己用foreach-object编写创建新列表的脚本,但我不明白如何使用重载定义(或者完全理解它们的含义(。

C# 中有很多示例,但我无法在 PoSH 中找到演示它的示例。

示例场景:

假设$DeletedUsers包含 PSCustomObject 类型的用户对象列表。具有典型的"用户"属性,例如部门或就业状态。此列表应该能够传递给函数,这些函数将更改 users 属性的状态,然后可以将这些属性添加到相同 Generic.List 类型的单独输出列表中。

目前示例函数的任何更改。

Function ProcessUser {
[Cmdletbinding()]
Param($DeletedUsers)
begin{$DeletedUsersClone = $($DeletedUsers).psobject.copy()} #OR similar
process{
$DeletedUsersClone | foreach { $_ | Add-Member -NotePropertyName 
"Processed" -NotePropertyValue "Processed:00"; $Outputlist.add($_)} 
}
}

影响原始$DeletedUsers,错误地将处理后的信息添加到应保持静态的列表中。

还有其他方法可以防止这影响脚本的最终目标,但问题是:

如何使用内置 C# 方法创建 System.Collections.Generic.List[System.object] 的 True 非引用克隆。

诀窍是使用显式强制转换为委托类型的脚本块。这看起来像:

$DeletedUsers.ConvertAll([converter[object,object]] {param ($i) <# do convert #> })

注意:

  • 正如后来所清楚的那样,OP正在寻找原始列表的深度克隆;也就是说,不仅应该克隆整个列表,还应该克隆其元素

  • 此答案仅显示如何创建浅表克隆(以及如何以只读方式传递列表(。

    • 请参阅Bruce Payette关于基于.ConvertAll方法的深度克隆方法的有用答案;对于[pscustomobject]实例,您将使用以下方法(但请注意,.psobject.Copy()仅创建[pscustomobject]实例本身的浅表副本(:

      $DeletedUsers.ConvertAll([converter[pscustomobject, pscustomobject]] {param ($obj) $obj.psobject.copy() })
      

  • 如果要将列表的浅层克隆传递给被叫方:

    • 传递[Collections.Generic.List[object]]::new($DeletedUsers)(PSv5+ 语法(
    • 或者,如果列表元素的类型未知,或者您不想重复它,则传递:$DeletedUsers.GetRange(0, $DeletedUsers.Count)
  • 如果您只想防止被叫方意外修改您的列表:

    • 传递$DeletedUsers.AsReadOnly()- 但是,这确实会更改类型,即更改为[Collections.ObjectModel.ReadOnlyCollection[object]]

相关内容

最新更新