这是 C# 中的一个简单场景:
var intList = new List<int>();
intList.Add(4);
intList.Add(7);
intList.Add(2);
intList.Add(9);
intList.Add(6);
foreach (var num in intList)
{
if (num == 9)
{
intList.Remove(num);
Console.WriteLine("Removed item: " + num);
}
Console.WriteLine("Number is: " + num);
}
这会抛出一个InvalidOperationException
因为我在枚举集合时修改集合。
现在考虑类似的 PowerShell 代码:
$intList = 4, 7, 2, 9, 6
foreach ($num in $intList)
{
if ($num -eq 9)
{
$intList = @($intList | Where-Object {$_ -ne $num})
Write-Host "Removed item: " $num
}
Write-Host "Number is: " $num
}
Write-Host $intList
该脚本实际上从列表中删除了数字 9!没有抛出异常。
现在,我知道 C# 示例使用 List 对象,而 PowerShell 示例使用数组,但是 PowerShell 如何枚举将在循环期间修改的集合?
The foreach构造会评估列表直至完成,并将结果存储在临时变量中,然后再开始迭代列表。当您进行实际删除时,您正在更新$intList引用新列表。换句话说,实际上在幕后做这样的事情:
$intList = 4, 7, 2, 9, 6
$tempList=$intList
foreach ($num in $tempList)
{
if ($num -eq 9)
{
$intList = @($intList | Where-Object {$_ -ne $num})
Write-Host "Removed item: " $num
}
Write-Host "Number is: " $num
}
Write-Host $intList
您致电:
$intList = @($intList | Where-Object {$_ -ne $num})
实际上创建了一个全新的列表,并删除了值。
如果您更改删除逻辑以删除列表中的最后一项 (6),那么我认为您会发现它仍然被打印,即使您认为它由于临时副本而被删除。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)