假设我有一个清单:
$DeletedUsers = New-Object System.Collections.Generic.List[System.object]
因此,我可以轻松地从集合中添加和删除用户。
我希望能够将此列表传递给执行某些操作的函数,但不修改原始列表,并且它必须保持相同的通用列表类型。
convertAll()
似乎完全符合我的要求,而不必使用foreach-object
自行创建新列表,但我不了解如何利用过载定义(或非常明白他们的意思)。
C#中有很多例子,但是我还没能找到一个在PoSH中演示它的例子。
示例场景:
假设$ DeletedUsers包含PSCustomObject类型的User对象列表。使用典型的" User"部门或就业状况等属性。此列表应该能够传递给将更改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]的真实,未引用的克隆。
答案 0 :(得分:2)
诀窍是使用带有显式强制转换的脚本块到委托类型。这看起来像:
$DeletedUsers.ConvertAll([converter[object,object]] {param ($i) <# do convert #> })
答案 1 :(得分:0)
注意:
后来很明显,OP正在寻找原始列表的深克隆;即,不仅要将整个清单克隆,还要其元素。
此答案仅说明如何创建浅克隆(以及如何以只读方式传递列表)。
请参阅Bruce Payette's helpful answer了解基于.ConvertAll
method的深层克隆方法;对于[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]]