带点的哈希表键
Posted
技术标签:
【中文标题】带点的哈希表键【英文标题】:Hashtable key with point 【发布时间】:2020-05-31 00:25:10 【问题描述】:如何发出带有点字符的哈希表键,例如FlatAppearance.BorderSize
,以便正确?
$Button = [System.Windows.Forms.Button] @
# This is not a valid entry
FlatAppearance.BorderSize = 0
$Button = [System.Windows.Forms.Button] @
# This is not a valid entry too
"FlatAppearance.BorderSize" = 0
$Button = [System.Windows.Forms.Button] @
# This is not a valid entry too too
FlatAppearance = @ BorderSize = 0
当然可以这样写
$Button = [System.Windows.Forms.Button] @
$Button.FlatAppearance.BorderSize = 0
不过,写在哈希表里面更方便。但是怎么做?谢谢
【问题讨论】:
【参考方案1】:由于Button
类型的.FlatAppearance
属性属于FlatButtonAppearance
类型,因此在这种情况下没有好的解决方案,因为FlatButtonAppearance
类型有没有公共的、无参数的构造函数。
如果是这样,您将能够编写:
using namespace System.Windows.Forms
$Button = [Button] @
# !! This is how you would generally do it, but
# !! IN THIS CASE IT DOESN'T WORK, due to lack of an appropriate constructor.
FlatAppearance = [FlatButtonAppearance] @ BorderSize = 0
上述语法类似于 C# 的 object initializer 语法,将在下一节中解释。
PowerShell 中的对象初始化语法:
对于从哈希表 (@ ...
) 或预先存在的 [pscustomobject]
实例[1]转换为类型文字 ([...]
) /sup> 执行隐式构造(隐式创建实例)然后多属性初始化才能工作,必须满足以下先决条件 :
目标类型必须有一个构造函数(可能还有其他[2]),即:
公开 and 无参数[3]类型的公共属性的名称必须与哈希表条目的键匹配,并且条目的值必须与目标属性具有相同或兼容的类型。
这使得 PowerShell 可以通过调用 new SomeType()
(PowerShell 语法中的 [SomeType]::new()
)在后台创建实例,然后从同名的哈希表条目中分配公共属性的值。
注意:PowerShell v3+ 中提供的此类转换实际上是语法糖,用于使用-Property
参数调用New-Object
cmdlet;只有后者在 v2 中有效。
除了查阅类型的文档之外,您还可以通过调用 PowerShell 提供的静态 ::new
方法轻松在 PowerShell 中检查类型的构造函数,不带括号 (()
):
PS> [System.Windows.Forms.FlatButtonAppearance]::new
# NO OUTPUT, which means the type has no public constructors at all.
# [ProcessStartInfo] has several public constructors, among them
# a public parameterless one, so you *can* initialize it by hashtable.
PS> [System.Diagnostics.ProcessStartInfo]::new
OverloadDefinitions
-------------------
System.Diagnostics.ProcessStartInfo new()
System.Diagnostics.ProcessStartInfo new(string fileName)
System.Diagnostics.ProcessStartInfo new(string fileName, string arguments)
确定类型的公共、可写实例属性:
PS> [System.Windows.Forms.FlatButtonAppearance].GetProperties('Public, Instance') |
? CanWrite | Select-Object Name, PropertyType
Name PropertyType
---- ------------
BorderSize System.Int32
BorderColor System.Drawing.Color
CheckedBackColor System.Drawing.Color
MouseDownBackColor System.Drawing.Color
MouseOverBackColor System.Drawing.Color
[1] 例如,这对于从 JSON 反序列化的对象很有用,这些对象变为 [pscustomobject]
实例;例如:$obj = ' "Text": "Submit" ' | ConvertFrom-Json; $button = [Button] $obj
[2] 边缘情况:不能也有具有以下参数类型之一的 single 参数公共构造函数,因为它会按原样绑定强制转换操作数:
[object]
或
从哈希表 (@ ...
) 投射时:[hashtable]
或 [System.Collections.IDictionary]
从[pscustomobject]
实例投射时:[psobject]
或[pscustomobject]
[3] 方便的是,如果你定义一个类型(类)而不声明任何构造函数,你会得到一个公共无参数的默认;例如,在以下 PowerShell 示例类中,Foo
隐式提供了这样一个构造函数:class Foo [string] $Bar ; $foo = [Foo] @ Bar = 'None'
【讨论】:
以上是关于带点的哈希表键的主要内容,如果未能解决你的问题,请参考以下文章