PowerShell - это оператор, всегда соответствующий PSCustomObject, при использовании в ForEach-Object - PullRequest
0 голосов
/ 12 ноября 2018

Использование PowerShell Core 6.1 на Mac.Похоже, что передача массива в ForEach-Object изменяет или упаковывает каждый элемент таким образом, что оператор -is считает, что все они являются объектами PSCustomObjects.

Позвольте мне продемонстрировать:

Настройка массиваиз четырех элементов разных типов (использование JSON, потому что именно отсюда поступают данные в моем реальном случае использования):

$a = '[4, "Hi", {}, true]' | ConvertFrom-Json

Итерируйте список по индексу и определите, какие из них являются PSCustomObjects:

0..3 | ForEach-Object { 
    $v = $a[$_]
    $t = $v.GetType().FullName
    $is = $v -is [PSCustomObject]
    "$t - $is"
}

Вывод (для меня) - это именно то, что я ожидал:

System.Int64 - False
System.String - False
System.Management.Automation.PSCustomObject - True
System.Boolean - False

Но если я просто передам массив в ForEach-Object:

$a | ForEach-Object { 
    $v = $_
    $t = $v.GetType().FullName
    $is = $v -is [PSCustomObject]
    "$t - $is"
}

Теперьвывод утверждает, что все четыре являются объектами PSCustomObject:

System.Int64 - True
System.String - True
System.Management.Automation.PSCustomObject - True
System.Boolean - True

Может кто-нибудь объяснить, что здесь происходит?

1 Ответ

0 голосов
/ 13 ноября 2018

PetSerAl , как он часто делает, предоставил критический указатель в комментарии:

Передача объектов в ForEach-Object оборачивает их в экземпляр [psobject], которыйзаставляет -is [pscustomobject] / -is [psobject] возвращать $True для любого входного объекта , потому что - смущает - [pscustomobject] совпадает с [psobject]: они оба являются ускорителями типов для [System.Management.Automation.PSObject] - против того, что можно было бы ожидать, [pscustomobject] это не сокращение для [System.Management.Automation.PSCustomObject].

Следовательно, проверяет входные объекты на наличие экземпляров [System.Management.Automation.PSCustomObject] вместо [pscustomobject]:

$a | ForEach-Object {
  $_ -is [System.Management.Automation.PSCustomObject]
}

Обратите внимание, что если вы используете foreach цикл , даже -is [pscustomobject] будет работать, потому что перечисляемые объекты тогда будут не , завернутый в дополнительный [psobject] экземпляр:

foreach ($element in $a) {
  $element -is [pscustomobject]
}

Это работает, потому что даже истинное [System.Management.Automation.PSCustomObject] технически также [System.Management.Automation.PSObject] за кадром.

...