有没有办法向 built-in/native powershell 对象(或类型?/class¿)添加方法?
Is there a way to add a method to built-in/native powershell object (or type?/class¿)?
有没有办法将方法添加到 built-in/native powershell 对象(或类型?/class¿)?
特别是,我在看你 [hashtable]
,但我想我的问题也是一般性问题...例如,我可能会看到想要为我的所有数组添加功能...
例如,我希望我所有的 [hashtable]
对象都具有方法:.AddAndOverwrite(..)
如果键存在,它将替换键的值;否则它会创建一个新密钥。
我似乎能够做到这一点的唯一方法是:
- 创建空
hashtable
、$HashTableNew
- 将
ScriptMethod
(s) 添加到 $HashTableNew
(即 .AddAndOverwrite(..)
)
- 然后当我使用它时,复制一份
$HashTableNew
$SomeOtherHashTable = $HashTableNew.PSObject.Copy()
这似乎不是“方式”...
注意: 我承认,这不是使用数据类型扩展方法的最佳示例(正如@SantiagoSquarzon 指出的那样)...但这是一个简单的问题,它允许在接受的答案中提供一个简单的例子;所以我故意保持原样,而不是将问题/扩展方法更改为 .foo()
返回 widgets
...
使用 Update-TypeData
.
确实有更好更简单的方法来更新整个类型
下面是一个将 .AddOrOverwrite
方法添加到哈希表的示例。
$TypeParam = @{
TypeName = 'System.Collections.Hashtable'
MemberType = 'ScriptMethod'
MemberName = 'AddOrOverwrite'
Value = { Param($Key, $Value) $this.$key = $Value }
}
Update-TypeData @TypeParam -Force
$SomeHashTable.AddOrOverwrite('aaa','2222222')
$this
,在方法定义的脚本块中,对应于目标对象引用,在本例中为哈希表。
-Force
每次都会覆盖定义,而不会错误地指出已经添加了类型。
该方法不是非常有用,因为它仅通过使用赋值就完成了哈希表自行管理得很好的事情,但它演示了如何做到这一点。
奖金示例
下面是一个示例,说明如何应用此原则并为字符串创建 2 个脚本属性(只读),以便您可以来回转换为 base 64。
$TypeParam = @{
TypeName = 'System.String'
MemberType = 'ScriptProperty'
Force = $true
}
Update-TypeData @TypeParam -MemberName 'Base64' -Value { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($this)) }
Update-TypeData @TypeParam -MemberName 'Base64Decoded' -Value { [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($this)) }
# Encode the string to base 64 (Output: U29tZVN0cmluZw==)
"SomeString".Base64
# Decode the string from Base64 (Output: SomeString)
"U29tZVN0cmluZw==".Base64Decoded
参考资料
Dr Scripto - Easily Update Powershell Type Data by Using a Cmdlet
有没有办法将方法添加到 built-in/native powershell 对象(或类型?/class¿)?
特别是,我在看你 [hashtable]
,但我想我的问题也是一般性问题...例如,我可能会看到想要为我的所有数组添加功能...
例如,我希望我所有的 [hashtable]
对象都具有方法:.AddAndOverwrite(..)
如果键存在,它将替换键的值;否则它会创建一个新密钥。
我似乎能够做到这一点的唯一方法是:
- 创建空
hashtable
、$HashTableNew
- 将
ScriptMethod
(s) 添加到$HashTableNew
(即.AddAndOverwrite(..)
) - 然后当我使用它时,复制一份
$HashTableNew
$SomeOtherHashTable = $HashTableNew.PSObject.Copy()
这似乎不是“方式”...
注意: 我承认,这不是使用数据类型扩展方法的最佳示例(正如@SantiagoSquarzon 指出的那样)...但这是一个简单的问题,它允许在接受的答案中提供一个简单的例子;所以我故意保持原样,而不是将问题/扩展方法更改为 .foo()
返回 widgets
...
使用 Update-TypeData
.
下面是一个将 .AddOrOverwrite
方法添加到哈希表的示例。
$TypeParam = @{
TypeName = 'System.Collections.Hashtable'
MemberType = 'ScriptMethod'
MemberName = 'AddOrOverwrite'
Value = { Param($Key, $Value) $this.$key = $Value }
}
Update-TypeData @TypeParam -Force
$SomeHashTable.AddOrOverwrite('aaa','2222222')
$this
,在方法定义的脚本块中,对应于目标对象引用,在本例中为哈希表。
-Force
每次都会覆盖定义,而不会错误地指出已经添加了类型。
该方法不是非常有用,因为它仅通过使用赋值就完成了哈希表自行管理得很好的事情,但它演示了如何做到这一点。
奖金示例
下面是一个示例,说明如何应用此原则并为字符串创建 2 个脚本属性(只读),以便您可以来回转换为 base 64。
$TypeParam = @{
TypeName = 'System.String'
MemberType = 'ScriptProperty'
Force = $true
}
Update-TypeData @TypeParam -MemberName 'Base64' -Value { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($this)) }
Update-TypeData @TypeParam -MemberName 'Base64Decoded' -Value { [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($this)) }
# Encode the string to base 64 (Output: U29tZVN0cmluZw==)
"SomeString".Base64
# Decode the string from Base64 (Output: SomeString)
"U29tZVN0cmluZw==".Base64Decoded
参考资料
Dr Scripto - Easily Update Powershell Type Data by Using a Cmdlet