Ответ уже дал @Sean, я просто предоставляю код, который показывает, что исходная коллекция не изменялась в течение foreach
: она перечисляет исходную коллекцию и, следовательно, противоречия нет.
# original array
$intList = 4, 7, 2, 9, 6
# make another reference to be used for watching of $intList replacement
$anotherReferenceToOriginal = $intList
# prove this: it is not a copy, it is a reference to the original:
# change [0] in the original, see the change through its reference
$intList[0] = 5
$anotherReferenceToOriginal[0] # it is 5, not 4
# foreach internally calls GetEnumerator() on $intList once;
# this enumerator is for the array, not the variable $intList
foreach ($num in $intList)
{
[object]::ReferenceEquals($anotherReferenceToOriginal, $intList)
if ($num -eq 9)
{
# this creates another array and $intList after assignment just contains
# a reference to this new array, the original is not changed, see later;
# this does not affect the loop enumerator and its collection
$intList = @($intList | Where-Object {$_ -ne $num})
Write-Host "Removed item: " $num
[object]::ReferenceEquals($anotherReferenceToOriginal, $intList)
}
Write-Host "Number is: " $num
}
# this is a new array, not the original
Write-Host $intList
# this is the original, it is not changed
Write-Host $anotherReferenceToOriginal
Выход:
5
True
Number is: 5
True
Number is: 7
True
Number is: 2
True
Removed item: 9
False
Number is: 9
False
Number is: 6
5 7 2 6
5 7 2 9 6
Мы видим, что $intList
изменяется, когда мы «удаляем элемент». Это только означает, что эта переменная теперь содержит ссылку на новый массив, это измененная переменная, а не массив. Цикл продолжает перечисление исходного массива, который не изменился, и $anotherReferenceToOriginal
все еще содержит ссылку на него.