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. 您是否对使用加速器与使用完整类型名称之间的差异进行了一些有趣的检查?
  2. 每当加速器可用时,是否应避免使用完整类型名称作为一般最佳做法?
  3. 如何检查,也许使用反射,加速器是否执行其他操作,而不仅仅是指向底层类?

查看静态方法:

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包装的任何对象(.Net,WMI,COM,ADSI或简单的属性包)上提供通用的反射API。

System.Management.Automation.PSCustomObject 只是一个实现细节。当您创建 PSObject 时,PSObject 必须包装一些东西。对于属性包,包装的对象是 System.Management.Automation.PSCustomObject.SelfInstance(内部成员)。此实例在PowerShell的正常使用中是隐藏的,观察它的唯一方法是使用反射。

属性包在 PowerShell 中以多种方式创建:

$o1 = [pscustomobject]@{Prop1 = 42}
$o2 = new-object psobject -Property @{Prop1 = 42 }

上面的 $o 1 和 $o 2 都将是 PSObject 的实例,PSObject 将包装 PSCustomObject.SelfInstance。PSCustomObject.SelfInstance在PowerShell内部使用,用于区分简单的属性包和包装任何其他对象。

最新更新