Powershell / .Net:获取方法返回的对象的引用

时间:2010-05-22 15:56:22

标签: .net powershell stack pass-by-reference byref

我通过编写一个简单的解析器来教自己PowerShell。我使用.Net框架类Collections.Stack。我想修改堆栈顶部的对象。

我知道我可以pop()关闭对象,修改它,然后push()重新开启它,但这让我觉得不够优雅。

首先,我试过这个:

$stk = new-object Collections.Stack
$stk.push( (,'My first value') )
( $stk.peek() ) += ,'| My second value'

引发了错误:

Assignment failed because [System.Collections.Stack] doesn't contain a settable property 'peek()'.
At C:\Development\StackOverflow\PowerShell-Stacks\test.ps1:3 char:12
+ ( $stk.peek <<<< () ) += ,'| My second value'
    + CategoryInfo          : InvalidOperation: (peek:String) [], RuntimeException
    + FullyQualifiedErrorId : ParameterizedPropertyAssignmentFailed

接下来我尝试了这个:

$ary = $stk.peek()
$ary += ,'| My second value'
write-host "Array is: $ary"
write-host "Stack top is: $($stk.peek())"

这可以防止错误,但仍然没有做正确的事情:

Array is: My first value | My second value
Stack top is: My first value

显然,分配给$ ary的是堆栈顶部对象的副本,所以当我在$ ary中的对象时,堆栈顶部的对象仍然存在不变。

最后,我读了teh [ref]类型,并尝试了这个:

$ary_ref = [ref]$stk.peek()
$ary_ref.value += ,'| My second value'
write-host "Referenced array is: $($ary_ref.value)"
write-host "Stack top is still: $($stk.peek())"

但仍然没有骰子:

Referenced array is: My first value | My second value
Stack top is still: My first value

我假设peek()方法返回对实际对象的引用,而不是克隆。如果是这样,那么引用似乎被PowerShell的表达式处理逻辑替换为克隆。

有人可以告诉我是否有办法做我想做的事情?或者我是否必须恢复为pop() /修改/ push()

2 个答案:

答案 0 :(得分:2)

数组始终具有固定大小。当您向数组添加项时,将创建一个长度增加的新数组,并将旧数组复制到新数组中。引用已隐式更改,因此您有一个包含2个元素的全新数组,而堆栈仍包含旧元素。改为使用列表。

答案 1 :(得分:1)

我明白了。是创建副本的“+ =”运算符。您似乎无法将元素添加到.Net数组中。如果我使用不同类型的对象,比如哈希表,我可以毫不费力地添加元素:

$stk.push( @{"1"="My first value"} )
$stk.peek()["2"]="| My second value"
write-host "Stack top keys: $($stk.peek().keys)"
write-host "Stack top values: $($stk.peek().values)"

哪个收益

Stack top keys: 1 2
Stack top values: My first value | My second value

或者对于更像数组的对象,Collections.ArrayList工作

$item = new-object Collections.ArrayList
$stk.push( $item )
$stk.peek().Add( "My first value" )
$stk.peek().Add( "| My second value" )
$obj = $stk.peek()
$obj.Add( "| My third value" )
write-host "Stack top is: $($stk.peek())"

哪个输出

Stack top is: My first value | My second value | My third value