问题描述
从本质上讲,作为Powershell脚本的一部分,我需要实现广度优先搜索.因此,我需要队列,并且认为System.Collections.Queue与其他任何队列一样好.但是,当我从队列中取出一个对象时,Powershell会丢失对我添加到该对象的所有属性的跟踪.
As part of my Powershell script I need to, essentially, implement breadth-first search. So, I need queue and figured System.Collections.Queue is as good as any other queue. However, when I get an object out of the queue, Powershell loses track of any properties I've added to the object.
这是怎么回事?如何访问我的财产?
What's going on here? How do I access my property?
此示例演示了问题:
$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的实例.好像它为我创建了一个在添加属性之前包装 $ object
的代码.因此,我需要创建一个 PSObject
或将出队的结果强制转换为 PSObject
.
Solution and More Questions
I found my mistake: add-member
modifies an instance of PSObject
not Object. It looks like it created one for me to wrap $object
before adding the property. So, I needed to either create a PSObject
or cast the result of dequeue to PSObject
.
我仍然不了解这里发生的一切.添加成员
是否修改了 $ object
以引用其创建的 PSObject
?如果不是,那么Powershell运行时如何知道 $ object
实际上是 PSObject
? $ object.gettype().name
是 Object
,而不是 PSCustomObject
.
I still don't understand everything that's going on here. Did add-member
modify $object
to refer to the PSObject
it created? If not, how did the Powershell run-time know that $object
was in fact a PSObject
? $object.gettype().name
is Object
not PSCustomObject
.
推荐答案
使用PsObject时,它可以工作.但是,我不知道为什么它不能在.NET对象上工作
When you use PsObject, it works. However, I have no idea why it doesn't work on the .NET Object
$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集合显然也是如此:
The same holds obviously for other .NET collections as well:
$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
这篇关于通过System.Collections.Queue传递对象时丢失类型信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!