我试图创建一个自动化的方法来设置对象的属性,当属性名称,类型和值是可变的。
示例:
我有一个WinForms窗体([System.Windows.Forms.Form]
),我想设置Size
、TopMost
和Dock
属性。我通过JSON获取这些值:
"properties": [
{
"name": "Size",
"type": "System.Drawing.Size",
"value": {
"width": 500,
"height": 500
}
},
{
"name": "TopMost",
"type": "System.Boolean",
"value": true
},
{
"name": "Dock",
"type": "System.Windows.Forms.DockStyle",
"value": "Right"
}
]
问题是,由于这些属性中的每一个都是不同的类型,所以它们都必须以不同的方式设置:
$form.Size = [System.Drawing.Size]::new(500, 500)
$form.TopMost = $true
$form.Dock = [System.Windows.Forms.DockStyle]::Right
现在我使用switch
语句:
switch -regex ($property.type){
"^System\.Drawing\.Size$" {
$form.$($property.name) = [system.drawing.size]::new($property.value.width, $property.value.height)
}
"^System\.Windows\.Forms\.DockStyle)$" {
$type = [type]$($property.type)
$form.$($property.name) = $type::$($property.value)
}
"^System\.(String|Boolean)$" {
$form.$($property.name) = $property.value
}
Default {
$type = [type]$($property.type)
$form.$($property.name) = $type::new($($property.value))
}
}
我使用的Default
case不适用于很多类型,所以每当我遇到我想使用的新类型时,我必须更新switch
语句。例如,System.Windows.Forms.FlowDirection
是一个类似于DockStyle
的枚举,所以我必须更新case语句:
"^System\.Windows\.Forms\.(DockStyle|FlowDirection))$" {
$type = [type]$($property.type)
$form.$($property.name) = $type::$($property.value)
}
有没有一个单一的、统一的方法,无论是什么类型的方法都能起作用?
2条答案
按热度按时间beq87vna1#
根据评论,没有防弹的内置机制来从你的json格式中脱离。这里有一个不完整的方法,虽然它概括了一些常见类型(枚举,值类型,满足某些约束的构造函数类)的处理......
首先,设置一个测试上下文(注意我已经改变了表单的大小,所以宽度和高度是不同的,这样我们就可以证明它们的设置是正确的):
然后我们可以使用反射来检查JSON中每个项目的表单属性。
根据表单属性的类型,我们可以做一些一般化的处理,这些处理将 * 在一些限制下 * 工作-例如,对于对象属性,* 必须 * 有一个公共构造函数,其参数名称与json中的字段匹配。如果对于给定的类型不是这样,你仍然需要为该类型添加一个特殊的处理程序。
由此产生的日志记录输出为:
生成的表单如下所示:
这应该可以处理 * 大多数 * 常见的
System.Windows.Forms.Form
属性,但是如果您试图将其用作其他类型的通用反序列化器,则可能会很快失败。lnlaulya2#
有没有一个单一的、统一的方法,无论是什么类型的方法都能起作用?
可能不会,但您可以改进当前的方法:
-as
运算符进行类型转换[System.Boolean]
添加特殊解析