提问人:Gordon 提问时间:2/19/2021 最后编辑:Gordon 更新时间:2/19/2021 访问量:453
Powershell 传递复杂对象 按值,而不是按引用
Powershell pass complex object By Value, not By Reference
问:
我正在尝试在一个有序的字典中处理一些数据,然后将其添加到另一个有序的字典中,我可以通过重新初始化我的临时字典来做到这一点,就像这样......
$collection = [Collections.Specialized.OrderedDictionary]::new()
foreach ($id in 1..5) {
$tempCollection = [Collections.Specialized.OrderedDictionary]::new()
foreach ($char in [Char]'a'..[Char]'e') {
$letter = ([Char]$char).ToString()
if ($id % 2 -eq 0) {
$letter = $letter.ToUpper()
}
$int = [Int][Char]$letter
$tempCollection.Add($letter, $int)
}
$collection.Add($id, $tempCollection)
}
foreach ($id in $collection.Keys) {
Write-Host "$id"
foreach ($key in $collection.$id.Keys) {
Write-Host " $key : $($collection.$id.$key)"
}
}
但是,我觉得重新初始化有点低效/不优雅,我宁愿只是那个临时变量。这导致了这个.......Clear()
$collection = [Collections.Specialized.OrderedDictionary]::new()
$tempCollection = [Collections.Specialized.OrderedDictionary]::new()
foreach ($id in 1..5) {
foreach ($char in [Char]'a'..[Char]'e') {
$letter = ([Char]$char).ToString()
if ($id % 2 -eq 0) {
$letter = $letter.ToUpper()
}
$int = [Int][Char]$letter
$tempCollection.Add($letter, $int)
}
$collection.Add($id, $tempCollection)
$tempCollection.Clear()
}
foreach ($id in $collection.Keys) {
Write-Host "$id"
foreach ($key in $collection.$id.Keys) {
Write-Host " $key : $($collection.$id.$key)"
}
}
问题在于,虽然字符串、int、char 等简单对象是通过值传递的,但所有复杂对象(如字典)都是通过引用传递的。所以我在每次迭代中都传递相同的字典,并且清除了 的最终状态,因此结果是 的 5 个空成员。$collection.Add($id, $tempCollection)
$tempCollection
$collection
我知道我可以使用此处概述的通常按值传递的东西强制为按引用。并且只是一个加速器。因此,我需要的是一种按值强制参数的方法,但既不起作用也不起作用,并且搜索似乎也没有返回任何有用的东西。上面链接的 PSReference doco 说[Ref]
[Ref]
System.Management.Automation.PSReference
[Val]
[ByVal]
System.Management.Automation.PSValue
此类用于描述这两种类型的引用:
A. 对值的引用:_value将保存被引用的值。
b. 对变量的引用:_value将持有 PSVariable 实例。
这让我觉得我可以以某种方式达到价值,但对于我的生活,我无法摸索如何。我是走在正确的轨道上,只是遗漏了一些东西,还是我完全误解了这个文档?
克隆似乎也是一个潜在的解决方案,即 ,但有序词典没有实现 ICloneable。 也不是一个选项,因为它不一定保持元素的顺序。从那以后也没有$collection.Add($id, $tempCollection.Clone())
.CopyTo()
.AsReadOnly()
AsReadOnly 方法在当前 OrderedDictionary 集合。对 OrderedDictionary 所做的更改 集合反映在只读副本中。OrderedDictionary 的实现方式也不像 PSObject 那样。
.copy()
我还尝试制作一个新变量,如下所示......
$newCollection = $tempCollection
$collection.Add($id, $newCollection)
$tempCollection.Clear()
那也行不通。因此,通过引用的复杂对象似乎不仅适用于传递的参数。
似乎我的 Ordered Dictionary 选择/需求几乎是问题的根源,但似乎需要 Ordered Dictionary 的未连接副本不会是不支持的边缘情况。
答: 暂无答案
评论
Deep Copy
$dictionary1 = $dictionary2
[Collections.Generic.List]
看起来是一样的,所以是有原因的,我相信知道为什么会带来一些更深层次的理解。:)OrderedDictionary
ICloneable