Как проверить (возможный) неизвестный тип?

PowerShell Core имеет семантическое управление версиями, который включает новый ускоритель типов под названием [semver] и основан на System.Management.Automation.SemanticVersion .

Чтобы протестировать этот конкретный тип в среде PowerShell Core, вы, вероятно, использовали бы синтаксис:

$PSVersionTable.PSVersion -is [semver]

Но если вы реализуете это в сценарии и запустите его в Windows PowerShell, вы получите сообщение об ошибке:

Unable to find type [semver].
At line:1 char:31
+ $PSVersionTable.PSVersion -is [semver]
+                               ~~~~~~~~
    + CategoryInfo          : InvalidOperation: (semver:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

Аналогичная ошибка появляется, когда я сравниваю его с именем типа (string):

$PSVersionTable.PSVersion -is `semver`
Cannot convert the "semver" value of type "System.String" to type "System.Type".
At line:1 char:1
+ $PSVersionTable.PSVersion -is 'semver'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

(Было бы хорошо/правильно, если бы PowerShell различал предоставление [Type] или 'String' в качестве сравнения и просто возвращал $False, если строка не может быть преобразована)

Как лучше всего проверить тип и предотвратить любую ошибку, если тип неизвестен (как это происходит с -is для определенных типов в конкретной среде)?


person iRon    schedule 05.09.2019    source источник
comment
что произойдет, если вы поместите тест типа в блок try/catch?   -  person Lee_Dailey    schedule 05.09.2019
comment
@Lee_Dailey, да, это действительно работает, но часто приводит к очень уродливым дополнительным утверждениям, например: Try{$IsType = $PSVersionTable.PSVersion -is [semver]} Catch{$IsType = $Null}; If ($IsType) {..., и я обычно стараюсь избегать блоков Try/Catch, насколько это возможно.   -  person iRon    schedule 05.09.2019
comment
я согласен, что это приводит к уродливому коду... но это можно обернуть в функцию. и метод в вашем ответе, и try/catch кажутся эффективными, поэтому используйте то, что соответствует вашему стилю. [усмехнуться]   -  person Lee_Dailey    schedule 05.09.2019


Ответы (2)


Спасибо vexx32 за этот ответ:
(см. также: Запрос функции: оператор -Is: подавить ошибку "Не удается преобразовать" № 10504)

'UnknownType' -as [type] -and $object -is [UnknownType]

E.g.:

'semver' -as [type] -and $PSVersionTable.PSVersion -is [semver]
person iRon    schedule 11.09.2019

Пока лучший ответ, который я могу придумать сам, это:

$Object.PSTypeNames -Contains '.NET Framework type'

e.g.:

$PSVersionTable.PSVersion.PSTypeNames -Contains 'System.Management.Automation.SemanticVersion'

Но это потребует использования ускорителей типов< /а> невозможно.

person iRon    schedule 05.09.2019