Перед самым странным поведением продолжайте действовать как тормоз [дубликат]

Вы используете объект, содержащий ссылку нулевого значения. Таким образом, он дает пустое исключение. В примере строковое значение равно null, и при проверке его длины произошло исключение.

Пример:

string value = null;
if (value.Length == 0) // <-- Causes exception
{
    Console.WriteLine(value); // <-- Never reached
}

Ошибка исключения:

Необработанное исключение:

System.NullReferenceException: ссылка на объект не установлена ​​в экземпляр объекта. в Program.Main ()

98
задан Justin Dearing 13 October 2011 в 21:24
поделиться

4 ответа

Просто используйте 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.

129
ответ дан Roman Kuzmin 28 August 2018 в 11:25
поделиться

Простой оператор 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"}}
0
ответ дан Alvin 28 August 2018 в 11:25
поделиться

Поскольку объект 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}
16
ответ дан manojlds 28 August 2018 в 11:25
поделиться

Еще одна альтернатива - это взломать, но вы можете обернуть свой блок в цикл, который будет выполняться один раз, таким образом продолжить будет иметь желаемый эффект:

1..100 | ForEach-Object {
    for($cont=$true;$cont;$cont=$false){
        if ($_ % 7 -ne 0 ) { continue; }
        Write-Host "$($_) is a multiple of 7"
        }
}
3
ответ дан zdan 28 August 2018 в 11:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: