Powershell V2 与 V4 范围界定差异

Powershell V2 vs V4 scoping differences

我很难理解这方面的文献。我希望有人能解释这里的区别,以便我能更好地理解我的脚本流程。

function select-bin {
    $objForm = New-Object System.Windows.Forms.Form 
    $objForm.Text = "Select a Bin"
    $objForm.Size = New-Object System.Drawing.Size(300,200) 
    $objForm.StartPosition = "CenterScreen"

    $x = @()

    # Create $OKButton and $objListBox ... removed code as not relevant.

    $OKButton.Add_Click({
        $x+=$objListBox.SelectedItems
        $objForm.Close()
    })

    $objForm.ShowDialog()
    if ($x) {
        return $x
    }
    else {
        return $null
    }
}

在上面的代码示例中,它在 Powershell V2 中运行良好,但在 V4 中,add_click 部分不起作用。它成功关闭了表单(在函数范围内创建)但未能更新 $x。

所以我想这是我的问题。

  1. 在 V2 中,add_click 部分是否被视为与函数在同一范围内? (我看到它能够更新 $x 的唯一方式)
  2. 发生这种改变数据的事件的正确方法是什么?我觉得在全局范围内声明 $x 有点多见,因为我只需要在函数中使用它。
  3. 在 V4 中,add_click 运行 属于什么范围?和V2的时候明显不一样,但是全局是运行吗?它是相对于 $OKButton 还是函数?我假设它是全局或函数的子项,但我真的不知道。

任何人都可以提供任何清晰度,我们将不胜感激。在我的公司迁移到 V4 之前,我有很多更新要做,因为我没有遵循范围界定的最佳实践(我的错误)。

在 V2 中,当 ScriptBlock 转换为委托时,会 运行 点源在恰好是当前范围的任何范围内。

通常,这是创建脚本块的作用域,所以事情自然会发生。但在某些情况下,它 运行 所在的范围与创建它的范围无关。

在 V4 中,这些脚本块 运行 在它们自己的作用域中 - 一个新作用域,它是当前作用域的子作用域,就像它们是一个函数并且您正常调用该函数一样(不是点源。 )

我认为最好的选择是使用以下其中一项(大致从好到坏):

  • $脚本:x
  • $x = Get-Variable -Scope 1 -Name x
  • $global:x