PowerShell类型加速器:PSObject vs PSCustomObject

时间:2016-03-09 14:25:04

标签: powershell powershell-v5.0 psobject pscustomobject type-accelerators

在PowerShell v3.0中PSCustomObject被引入。它就像PSObject,但更好。除了其他改进(例如保留属性顺序)之外,还可以简化从哈希表中创建对象:

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

现在看来很明显这句话:

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

会以同样的方式工作,因为PSCustomObject是"别名"完整的命名空间+类名。相反,我得到一个错误:

  

无法转换" System.Collections.Hashtable" type" 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. 您是否在使用加速器与使用完整类型名称之间存在一些有趣的差异?
  2. 当加速器作为一般最佳实践可用时,是否应避免使用完整类型名称?
  3. 如果加速器执行除了指向基础类之外的其他事情,如何检查,也许使用反射?

2 个答案:

答案 0 :(得分:6)

查看静态方法:

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...

类型加速器添加了几个新的静态方法。我怀疑它正在使用其中一个作为构造函数。

答案 1 :(得分:2)

[PSObject]和[PSCustomObject]是同一类型的别名 - System.Management.Automation.PSObject。我不能说它有充分的理由,但它至少暗示了两个不同的目的,也许这就足够了。

System.Management.Automation.PSObject用于包装对象。它被引入以提供PowerShell包装的任何对象的公共反射API - .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内部使用,用于区分简单属性包和包装任何其他对象。