15

在 PowerShell v3.0PSCustomObject中引入。有点像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. 如果加速器不仅仅指向底层类,如何检查,也许使用反射?
4

2 回答 2

7

查看静态方法:

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

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

于 2016-03-09T14:48:27.123 回答
4

[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 }

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

于 2016-03-13T02:31:44.867 回答