2011-05-26 89 views
2

作爲我的Powershell腳本的一部分,我需要實質上實現廣度優先搜索。所以,我需要隊列和計算System.Collections.Queue是一樣好任何其他隊列。但是,當我將對象從隊列中取出時,Powershell會失去跟蹤已添加到對象中的任何屬性。在通過System.Collections.Queue傳遞對象時丟失類型信息

這是怎麼回事?我如何訪問我的財產?

此示例說明問題:

$object = new-object object 
add-member -membertype noteproperty -name AnInteger -value 2 -inputobject $object 
$queue = new-object system.collections.queue 
$queue.enqueue($object) 
$dequeued = $queue.dequeue() 

# 1. True - both variables refer to the same object. 
$object -eq $dequeued 
# 2. True - using the original variable, can access the property. 
$object.AnInteger -ne $null 
# 3. False. Err, What? 
$dequeued.AnInteger -ne $null 

解決方案和更多的問題

,我發現我的錯誤:add-member修改的PSObject實例不會反對。它看起來像它創造了一個爲我包裝$object之前添加屬性。所以,我需要創建一個PSObject或將出隊結果投給PSObject

我還是不明白這裏發生的一切。 add-member是否修改$object來參考它創建的PSObject?如果不是的話,Powershell運行時如何知道$object實際上是PSObject$object.gettype().nameObject而不是PSCustomObject

回答

0

看來,dequeue()實際上是基於要傳回給您的原始對象類型創建新對象,這意味着添加的屬性將不會包含在返回的對象中。這是一種醜陋,我不知道這是否有助於或沒有,但我沒有得到它的序列化進入隊列對象的工作,和反序列化它,當它回來了

$object = new-object object 
add-member -membertype noteproperty -name AnInteger -value 2 -inputobject $object 
$queue = new-object system.collections.queue 
$queue.enqueue((convertto-csv $object)) 
$dequeued = convertfrom-csv $queue.dequeue() 
$dequeued 



AnInteger 
--------- 
2   
2

當你使用PsObject時,它可以工作。但是,我不知道爲什麼它不會對.NET對象

$object = new-object PsObject -property @{AnInteger=2} 
$queue = new-object system.collections.queue 
$queue.enqueue($object) 
$dequeued = $queue.dequeue() 

$object.Aninteger -eq $dequeued.AnInteger # returns True 

相同的工作抱顯然對於其他.NET集合,以及:

$mynum = 10 | add-member noteproperty MySecret 12345 -pass 
$mynum.mysecret 
$list = New-Object collections.arraylist 
$list.Add($mynum) 
$list[0].mysecret 

$list[0] | fl * -force # shows nothing 
$mynum | fl * -force # shows mysecret 
+0

添加成員只能直接修改PSObjects,因爲那些可以有類型擴展的成員。要修改常規對象,請使用-PassThru並獲取新對象。 '$ Object = Add-Member -input $ Object ... -PassThru'。這實際上會創建一個PSObject來包裝常規對象。新的PSObject對你來說基本上是透明的。 – JasonMArcher 2011-06-18 17:38:18

0

你的代碼是確定的,只是改變第一行

$object = new-object PSObject 

你也許一個C#developper這就是儘管PSObject爲什麼你的代碼對象。我不確定要真正理解爲什麼,但是PSObject已經獲得了用於保留noteproperties的必要代碼。

爲了寫你也可以寫更少的線下創建PSCustomObject

$object = "" | select AnInteger,Astring 
$object.AnInteger = 12 
$object.AString = "coucou" 

結果:

PS> $object.GetType() 

IsPublic IsSerial Name      BaseType 
-------- -------- ----      -------- 
True  False PSCustomObject   System.Object 

它可以在你的代碼:

$queue = new-object system.collections.queue 
$queue.enqueue($object) 
$dequeued = $queue.dequeue() 

$dequeued 
$dequeued.AnInteger 
$dequeued.Astring 

它會給

AnInteger Astring                   
--------- -------                   
     12 coucou                   
12 
coucou