Вы используете объект, содержащий ссылку нулевого значения. Таким образом, он дает пустое исключение. В примере строковое значение равно null, и при проверке его длины произошло исключение.
Пример:
string value = null;
if (value.Length == 0) // <-- Causes exception
{
Console.WriteLine(value); // <-- Never reached
}
Ошибка исключения:
Необработанное исключение:
System.NullReferenceException: ссылка на объект не установлена в экземпляр объекта. в Program.Main ()
blockquote>
Просто используйте return
вместо continue
. Этот return
возвращается из блока сценария, который вызывается ForEach-Object
на конкретной итерации, таким образом, он имитирует continue
в цикле.
1..100 | ForEach-Object {
if ($_ % 7 -ne 0 ) { return }
Write-Host "$($_) is a multiple of 7"
}
Это вопрос, который нужно сохранить в виду рефакторинга. Иногда хочется преобразовать блок оператора foreach
в конвейер с командлетом ForEach-Object
(у него даже есть псевдоним foreach
, который помогает легко сделать это преобразование и сделать ошибки тоже). Все continue
следует заменить на return
.
P.S. К сожалению, не так легко имитировать break
в ForEach-Object
.
Простой оператор else заставляет его работать как
1..100 | ForEach-Object {
if ($_ % 7 -ne 0 ) {
#do nothing
} else {
Write-Host "$($_) is a multiple of 7"
}
}
или в одном конвейере
1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) {} else {Write-Host "$($_) is a multiple of 7"}}
, но более элегантным решением является инвертирование вашего теста и создание вывода за ваши успехи
1..100 | ForEach-Object {if ($_ % 7 -eq 0 ) {Write-Host "$($_) is a multiple of 7"}}
Поскольку объект For-Each
является командлетом, а не циклом, и continue / break не применяются к нему.
Например, если у вас есть:
$b = 1,2,3
foreach($a in $b){
$a | foreach { if($_ -eq 2) {continue;} else {write-host $_} }
write-host "after"
}
, вы будет выводиться как:
1
after
3
after
Это связано с тем, что continue применяется к внешнему циклу foreach, а не к командлету foreach-object. В отсутствие петли, внешний уровень, поэтому дает вам впечатление, что это действует как разрыв.
Итак, как вы продолжаете, как поведение? Один из способов - это объект-объект:
1..100 | ?{ $_ % 7 -eq 0} | %{write-host $_ is a mutliple of 7}
Еще одна альтернатива - это взломать, но вы можете обернуть свой блок в цикл, который будет выполняться один раз, таким образом продолжить будет иметь желаемый эффект:
1..100 | ForEach-Object {
for($cont=$true;$cont;$cont=$false){
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
}