循环中的 Powershell 值失去其值(value)

标签 powershell

原谅标题,我真的不知道如何解释我所看到的。

示例代码:

    $SampleValues = 1..5
    $Result = "" | Select ID
    $Results = @()  

    $SampleValues | %{
        $Result.ID = $_
        $Results += $Result
    }

$Results

这很简单:

  • 创建一个包含 5 个数字的数组以用于循环
  • 使用名为 ID 的 NoteProperty 创建一个临时变量
  • 创建一个空数组来存储结果
  • 遍历 5 个数字中的每一个,将它们分配给一个临时变量,然后将其附加到一个数组中。

预期结果是 1,2,3,4,5,但运行时返回 5,5,5,5,5

这是一个从更复杂的脚本中提取的准系统示例,我试图弄清楚为什么结果会是这样。在每次迭代中,所有已添加到 $Results 的元素都将其值更新为最新值。我已经测试了将所有内容强制到 $Script: 或 $Global: 范围并获得相同的结果。

我找到的唯一解决方案如下,它将 $Result 声明移动到循环中。

    $SampleValues = 1..5
    $Results = @()

$SampleValues | %{
    $Result = "" | Select ID
    $Result.ID = $_
    $Results += $Result
    }

这有效(您的结果为 1,2,3,4,5)。看起来 $Results 只是持有对单个 $Result 对象的多个引用,但为什么将它移到循环中可以解决问题?在这个例子中 $Result 是一个字符串,所以它可能会在每次迭代时创建一个新对象,但即使我强制 $Result 是一个整数(它不应该重新创建一个新对象,因为整数不像字符串那样不可变)它仍然解决了问题,我得到了我预期的结果。

如果有人对这解决问题的确切原因有任何见解,我很好奇。有很多替代方案可供我实现,但不具体理解为什么这种方式会困扰我。

最佳答案

它通过进入循环来解决问题,因为这样您每次都创建一个新的 $Result 对象,而不是更改同一个对象的值(在数组中引用了 5 次)。

与是否使用""| 没有任何关系选择 ID123 |选择 ID,因为它只是 PSCustomObject 上的一种属性,它仍然是引用类型而不是值类型。

请记住,Powershell 内部全是 .NET。下面是一些 C#,类似于 Powershell 在您的第一个示例中所做的导致所有 5 的操作(希望您了解 C#):

var SampleValues = new []{1,2,3,4,5};
var Result = new CustomObject(){ ID = "" };
var Results = new List<Object>();

foreach (var _ in SampleValues) {
    Result.ID = _;
    Results.Add(Result);
}

希望您可以看到在 foreach 循环中移动 var Result = new CustomObject(){ ID = ""} 会使其更好地工作,并且是相同的概念在 Powershell 中也是如此。

关于循环中的 Powershell 值失去其值(value),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6230838/

相关文章:

powershell - AD GUI显示PowerShell返回空的属性

powershell - 如何将 -Verbose 传播到模块函数?

.net - Powershell 和覆盖比较运算符

windows - 通过 Powershell 或 Batch 将文件从 Windows 转换为 UNIX

string - 传递给参数的值何时需要引号?

mysql - Powershell 和 MySql ExecuteNonQuery 的问题

python - 需要 'package' 参数来执行相对导入

powershell - Azure SFTP 连接器,创建后无法编辑应用程序设置值

powershell - Add-Type-具有结构参数的处理函数

azure - 如何在 Azure CLI 中显示死信消息