return
и [pscustomobject]
здесь, в некотором смысле, красные сельди.
То, к чему это сводится:
Неявный вывод / выражение в сравнении с производимым командлетом выводом; использование return
относится к первой категории, использование Write-Output
ко второй.
объекты, заключенные в в основном невидимые [psobject]
экземпляры только в командлет выходные данные.
# implicit / expression output: NO [psobject] wrapper:
@{ "aaa" = "bbb" } -is [psobject] # -> $False
# Cmdlet-produced output: [psobject]-wrapped
(Write-Output @{ "aaa" = "bbb" }) -is [psobject] # -> $True
Обратите внимание, что, что удивительно, [pscustomobject]
совпадает с [psobject]
: они оба относятся к типу [System.Management.Automation.PSObject]
, который является обычно невидимым вспомогательным типом , который PowerShell использует за кулисами.
(Чтобы добавить к путанице, - это отдельный [System.Management.Automation.PSCustomObject]
тип.)
По большей части эта дополнительная оболочка [psobject]
является доброкачественной - она в основном ведет себя так же, как обернутый объект напрямую - но есть случаи, когда она вызывает слегка другое поведение (см. Ниже).
И есть ли обобщенный способ определения отличия от кода, кроме явной проверки, является ли каждая хеш-таблица, имеющаяся у меня в переменной, также объектом pscustomobject
Обратите внимание, что хеш-таблица не пользовательский объект PS - он появляется таким образом для - любого - [psobject]
-обернутого объекта, поскольку [pscustomobject]
совпадает с [psobject]
.
Чтобы обнаружить настоящий пользовательский объект PS - созданный с помощью [pscustomobject] @{ ... }
или New-Object PSCustomObject
/ New-Object PSObject
или созданный такими командлетами, как Select-Object
и Import-Csv
- используйте:
$obj -is [System.Management.Automation.PSCustomObject] # NOT just [pscustomobject]!
Обратите внимание, что использование связанного оператора -as
с настоящим пользовательским объектом PS не работает в Windows PowerShell v5.1 / PowerShell Core v6.1.0 - см. Ниже.
В качестве примера ситуации, когда дополнительная оболочка [psobject]
является доброкачественной, вы все равно можете напрямую проверить даже обернутый объект на его тип:
(Write-Output @{ "aaa" = "bbb" }) -is [hashtable] # $True
То есть, несмотря на упаковщик, -is
все еще распознает тип wrapped .
Поэтому, как это ни парадоксально, и -is [psobject]
, и -is [hashtable]
возвращают $True
в этом случае, даже если эти типы не связаны.
Нет веских причин для этих несоответствий и они кажутся мне утечкой абстракций (реализациями): внутренние конструкции случайно выглядывают из-за занавеса.
Следующие проблемы GitHub обсуждают эти поведения: