我只是想知道为什么它会起作用:
$s = "hi there"
$s = Add-Member -InputObject $s -MemberType AliasProperty -Name Length2 -Value Length -PassThru
$s | gm -MemberType AliasProperty #the property is there
$s.Length2 #8
这意味着:别名属性Length2存在,但这不起作用:
$s = dir
$s = Add-Member -InputObject $s -MemberType AliasProperty -Name Length2 -Value Length -PassThru
$s | gm -MemberType AliasProperty #the property is not there
意味着:没有别名属性Length2,但令人惊讶的是:
$s.Length2 #458
工作正常吗
1条答案
按热度按时间t98cgbkg1#
$s = dir
由于
dir
是Get-ChildItem
的内置别名,这 * 通常 * 会导致在$s
中存储 * 数组 *,即只要存在 * 两个或更多 * 子项(文件或子目录)。[1]$s = Add-Member -InputObject $s ...
由于使用了
Add-Member
的-InputObject
参数,您将alias属性(作为ETS (Extended Type System)成员)添加到 * 数组本身 *。$s | gm -MemberType AliasProperty
相比之下,由于在这里使用了 * 枚举 * 数组的 * 管道 *,因此将
$s
中存储的数组的 * 元素 * 发送到Get-Member
(其内置别名为gm
)-并且这些元素 * 没有 * 您的alias属性。$s.Length2 #458
在这里,您直接访问数组上的alias属性,因此可以正常工作。
至于你的 * 第一次 * 尝试(如预期的那样工作):
$s
是一个 scalar(单个对象),即一个[string]
示例,您将alias属性直接附加到它。[string]
示例的自定义成员。$s | gm -MemberType AliasProperty
)发送标量时,标量会按原样发送,因此Get-Member
(gm
)能够找到其.Length2
别名属性。可选阅读:为什么最好避免将ETS (Extended Type System)成员附加到 *
[string]
* 和 *.NET值类型 * 的 * 示例 *:注意事项:
Add-Member
能够添加到.NET类型的 * 示例 * 的任何类型的ETS成员,特别是更常见的NoteProperty
成员。[string]
示例**,因为它们需要一个 * 不可见的[psobject]
Package 器 *,该 Package 器 * 容易丢失 *,例如在字符串操作和强类型参数绑定期间,导致ETS成员丢失;例如:[int]
(System.Int32
);在类型上调用.IsValueType
来检查),原因类似:它们也可能在强类型参数绑定 * 和 * 过程中丢失,相反-因为PowerShell内部缓存了从0
到100
的[int]
示例,包括在内-当这些数字被用作 * 文字 * 时,可能会使ETS成员意外出现。注意事项:
[psobject]
Package 器的必要性,它需要在上面的Add-Member
调用中使用-PassThru
,沿着 * 将结果重新分配给原始变量 *($s = Add-Member -PassThru -InputObject $s ...
)[string]
* 以外的.NET reference types * 的装饰示例,这种调用形式是 * 不 * 必要的,并且这些示例不受上述问题的影响。可选阅读:* 示例 * 级别与 * 类型 * 级别ETS成员:
ETS成员也可以在 type 级别定义(而不是在 instance 级别,即 * 仅用于特定对象 *),即通过
Update-TypeData
,这是 * 通常优选的 *,尽管并不总是要求/可能的。AliasProperty
成员的情况下,type-level 定义是更好的选择,因为给定类型的 * 所有示例 * 都会自动具有此属性:NoteProperty
成员值的情况下,如果该值可以通过ScriptProperty
成员从示例的类型原生属性 * 派生 *,则作为替代的 type-level 定义仅是一个选项,即其值是 * 动态计算 * 的属性,通过script block({ ... }
),可以通过自动$this
变量作用于手头的示例;例如:[1]具体来说,它是一个包含
System.IO.FileInfo
和/或System.IO.DirectoryInfo
示例的[object[]]
数组。