奇怪的行为 -> .GetEnumerator() | .Reset() -> 寻找解决方法

Strange behaviour -> .GetEnumerator() | .Reset() -> Looking for a way around

我在 PowerShell 中使用一个简单的 XML 文件,由于我使用 GetEnumerator() 方法,我在使用我的脚本时看到一些奇怪的东西。当我使用 GetEnumerator() 方法将某些内容保存在对象中时,我只能使用该对象一次。之后我必须重新设置才能再次使用它。

我想摆脱这种行为。下面是一个示例脚本,它基本上展示了我如何在我的脚本中使用它。在函数的真实脚本中,我经常使用变量 $ControlObject,每次都必须重新设置它。

我怎样才能简单地防止这种情况发生?

$XMLTargetPath = Join-Path -Path $PSScriptRoot -ChildPath "XMLConfig.xml"

# Save XML in File for easy and fast reproduction
$XMLContentForFile = [xml]@"
<OuterNode>
  <BaseSettings>
    <Setting1>Blabla</Setting1>
  </BaseSettings>
  <DynamicSettings>
    <item>
        <Number>1</Number>
        <Name>January</Name>
    </item>
    <item>
        <Number>2</Number>
        <Name>February</Name>
    </item>
  </DynamicSettings>
</OuterNode>
"@
$XMLContentForFile.Save($XMLTargetPath)

function MyFunction {
    Param(
        [Parameter(Mandatory=$true, Position=0)]
        $ControlObject
    )

    $ControlObject     # Output the Object
    $ControlObject     # PROBLEM - I get no output ...

    # I need to make a reset to output the object again ...
    $ControlObject.Reset()
    $ControlObject
}

[xml]$xml = Get-Content -Path $XMLTargetPath

# Pass the XML-Node "Dynamic-Settings" into Function
MyFunction -ControlObject $xml.OuterNode.DynamicSettings.GetEnumerator()

我认为您误解了枚举器和 PowerShell 默认输出的工作方式。 PowerShell automagically appends | Out-Default 用于输出处理:

It calls the engine to get the prompt but then it displays it and collects user input. It then takes that input, concatenates | Out-Default and submits it to the engine for execution. … YES, under the covers every command entered in through the console host is piped to Out-Default.

但是,管道会自动展开枚举器(否则它将无法显示枚举或可枚举集合的元素)。因此,仅回显一个变量在本质上与遍历 enumerator:

相同
while ($ControlObject.MoveNext()) {
    $ControlObject.Current
}

枚举器在输出操作后位于枚举的末尾,所以需要先将其移动到开头,然后才能再次枚举元素。这就是 Reset() 所做的。

为什么管道不自动重置枚举?我不知道,但可能不会产生无限循环。

底线:蛋糕不能吃。需要展开枚举以便显示元素,并且由于枚举不会自动重置,您需要自己执行此操作才能再次枚举元素。

如果您只想要所选节点的嵌套元素,您应该使用 ChildNodes 属性 而不是枚举器。

MyFunction -ControlObject $xml.OuterNode.DynamicSettings.ChildNodes