PowerShell类型加速器:PSObject vs PSCustomObject

PowerShell类型加速器:PSObject vs PSCustomObject,powershell,powershell-5.0,psobject,pscustomobject,type-accelerators,Powershell,Powershell 5.0,Psobject,Pscustomobject,Type Accelerators,在PowerShell v3.0中引入了PSCustomObject。这就像PSObject,但更好。在其他改进(例如保留属性顺序)中,简化了从哈希表创建对象: [PSCustomObject]@{one=1; two=2;} 现在看来很明显,这句话: [System.Management.Automation.PSCustomObject]@{one=1; two=2;} 将以同样的方式工作,因为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
类-这意味着使用加速器可以做很多其他事情,而不仅仅是缩短代码

关于这个问题,我的问题是:

  • 您是否有一些有趣的例子来说明使用加速器和使用完整类型名称之间的区别
  • 当加速器作为一般最佳实践可用时,是否应避免使用完整类型名称
  • 如何检查(可能是使用反射)加速器是否做了除了指向底层类之外的其他事情

  • 查看静态方法:

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

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

    [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。PowerShell内部使用PSCustomObject.SelfInstance来区分简单属性包和包装任何其他对象之间的区别。

    如果您反编译
    System.Management.Automation.Language.Compiler.VisitConvertExpression
    ,则可以看到对三种类型名称有特殊处理:
    ordered
    PSCustomObject
    ref
    。你好,Jason。
    Get Member
    .GetType()
    都将$o1和$o2作为PSCustomObject而不是PSObject的实例进行报告。但是,如果我将第三个对象创建为
    $o3=[PSObject]@{Prop1=42}
    ,则该对象不同。我的观点是,上面的答案令人困惑,因为在powershell
    [PSObject]
    [pscustomobject]
    当然不要这样做。是的,这有点让人困惑,部分是我的错,部分是设计。我错过了调用GetType()作为查看pscustomobject的一种方式。从V3开始,对[pscustomobject]的强制转换在解析器中被特别处理,在此之前,它将等同于对[psobject]的强制转换但是,底线是类型(和单例实例)System.Management.Automation.PSCustomObject是一个实现细节。如果操作数是散列文字,则转换[PSCustomObject]很有用,否则它相当于[psobject]转换。@JasonShirk如果内存可用,则使用
    [PSCustomObject]
    转换(n v3或更高版本)在某些受限语言模式下可能会失败,而其他一些方法(
    newobject
    Select Object
    ?)会在相同的上下文中工作。我现在不记得细节了,因为我几年前发现了(困难的方法)。