Усилители типа PowerShell: PSObject vs PSCustomObject
В PowerShell v3.0 PSCustomObject
. Это как PSObject
, но лучше. Среди других улучшений (например, сохранение порядка сохранения) упрощается создание объекта из хэш-таблицы:
[PSCustomObject]@{one=1; two=2;}
Теперь кажется очевидным, что это утверждение:
[System.Management.Automation.PSCustomObject]@{one=1; two=2;}
будет работать одинаково, потому что PSCustomObject
является "псевдонимом" для полного пространства имен + имя класса. Вместо этого я получаю сообщение об ошибке:
Невозможно преобразовать значение "System.Collections.Hashtable" типа "System.Collections.Hashtable", чтобы ввести "System.Management.Automation.PSCustomObject".
Я перечислил ускорители для обоих типов объектов:
[accelerators]::get.GetEnumerator() | where key -Like ps*object
Key Value
--- -----
psobject System.Management.Automation.PSObject
pscustomobject System.Management.Automation.PSObject
и обнаружил, что оба ссылаются на один и тот же класс PSObject
- это означает, что использование ускорителей может сделать кучу других вещей, чем просто сделать код короче.
Мои вопросы по этой проблеме:
- Есть ли у вас интересные примеры различий между использованием ускорителя и использованием полного имени типа?
- Следует ли избегать использования полного имени типа всякий раз, когда ускоритель доступен в качестве общей лучшей практики?
- Как проверить, может быть, использовать отражение, если ускоритель делает другие вещи, а не просто указывает на базовый класс?
Ответы
Ответ 1
Глядя на статические методы:
PS C:\> [PSCustomObject] | gm -Static -MemberType Method
TypeName: System.Management.Automation.PSObject
Name MemberType Definition
---- ---------- ----------
AsPSObject Method static psobject AsPSObject(System.Object obj)
Equals Method static bool Equals(System.Object objA, System.Object objB)
new Method psobject new(), psobject new(System.Object obj)
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object o...
PS C:\> [System.Management.Automation.PSCustomObject] | gm -Static -MemberType Method
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method static bool Equals(System.Object objA, System.Object objB)
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object o...
У ускорителя типа есть несколько новых статических методов. Я подозреваю, что он использует один из них в качестве конструктора.
Ответ 2
[PSObject] и [PSCustomObject] - это псевдонимы для того же типа - System.Management.Automation.PSObject. Я не могу сказать, что для этого есть веская причина, но это, по крайней мере, наводит на размышления о двух разных целях и, возможно, об этой причине.
System.Management.Automation.PSObject используется для обертывания объектов. Он был представлен для обеспечения общего отражения api над любым объектом, который PowerShell обертывает -.Net, WMI, COM, ADSI или простые пакеты свойств.
System.Management.Automation.PSCustomObject - это просто деталь реализации. Когда вы создаете PSObject, PSObject должен что-то обернуть. Для пакетов свойств объект, обернутый, - System.Management.Automation.PSCustomObject.SelfInstance(внутренний член.) Этот экземпляр скрыт от обычного использования PowerShell, единственный способ его наблюдения - с отражением.
Пакеты свойств создаются несколькими способами в PowerShell:
$o1 = [pscustomobject]@{Prop1 = 42}
$o2 = new-object psobject -Property @{Prop1 = 42 }
Оба $o1 и $o2 выше будут экземпляром PSObject, а PSObject будет обернуть PSCustomObject.SelfInstance. PSCustomObject.SelfInstance используется внутри PowerShell, чтобы рассказать о различии между простой сумкой свойств и обернуть любой другой объект.