12

В PowerShell v3.0 PSCustomObject. Это как PSObject, но лучше. Среди других улучшений (например, порядок свойств сохраняется), создавая объект из хеш-таблицы упрощается:Ускорители типа PowerShell: PSObject vs PSCustomObject

[PSCustomObject]@{one=1; two=2;} 

Теперь кажется очевидным, что это утверждение:

[System.Management.Automation.PSCustomObject]@{one=1; two=2;} 

будет работать точно так же, потому что PSCustomObject является «псевдоним» для полного пространства имен + имя класса. Вместо этого я получаю сообщение об ошибке:

Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "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. У вас есть некоторые интересные examaples различий между использованием ускорителя против использования полного имени типа?
  2. Следует избегать использования полного типа, всякий раз, когда ускоритель доступен в качестве общей лучшей практики?
  3. Как проверить, может быть, использовать отражение, если ускоритель выполняет другие действия, а не просто указывает на базовый класс?
+4

Если вы декомпилируете 'System.Management.Automation.Language.Compiler.VisitConvertExpression', то вы можете увидеть, что есть специальная обработка для трех типов имен: 'ordered',' PSCustomObject' и 'ref'. – PetSerAl

ответ

5

Глядя на статические методы:

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, чтобы рассказать о различии между простой сумкой свойств и обернуть любой другой объект.

+0

Привет, Джейсон. И «Get-Member», и «.GetType()» сообщают как $ o1, так и $ o2 как экземпляры PSCustomObject, а не PSObject. –

+0

Если, однако, я создаю третий объект как '$ o3 = [psobject] @ {Prop1 = 42}', этот объект отличается. –

+1

Моя точка зрения заключается в том, что приведенный выше ответ путают, потому что в powershell '[psobject]' и '[pscustomobject]' обязательно не действуют одинаково. –

Смежные вопросы