我正在使用Xml存储应用程序设置,在运行时更改并在应用程序执行期间多次序列化和反序列化。
有一个Xml元素可以容纳任何可序列化类型,并且应该从属性类型为Object
的序列化序列化和反序列化。
[Serializable]
public class SetpointPoint
{
[XmlAttribute]
public string InstrumentName { get; set; }
[XmlAttribute]
public string Property { get; set; }
[XmlElement]
public object Value { get; set; }
} // (not comprehensive, only important properties displayed)
XML,
<?xml version="1.0" encoding="utf-8"?>
<StationSetpoints xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.w3schools.com StationSetpoints.xsd">
<Setpoint PartNumber="107983">
<Point InstrumentName="PD Stage" Property="SetPoint">
<Value xsi:type="xsd:string">3</Value>
</Point>
<Point InstrumentName="TR Camera" Property="MeasurementRectangle" StationSetpointMemberType="Property">
<Value xsi:type="xsd:string">{X=145,Y=114,Width=160,Height=75}</Value>
</Point>
</Setpoint>
</StationSetpoints>
我反序列化Xml并解析属性以通过"InstrumentName"查找仪器对象,该仪器将具有与Xml属性"Property"相同的属性,并且我的意图是将该仪器.property设置为xml中的Value元素。像反射一样轻松地转换对象(在vb.net中)。
Dim ii = InstrumentLoader.Factory.GetNamed(point.InstrumentName)
Dim pi = ii.GetType().GetProperty(point.Property)
Dim tt = pi.PropertyType
Dim vt = Convert.ChangeType(point.Value, tt)
pi.SetValue(ii, vt)
没错,如果 point.Value 是一个对象的话,那么这将起作用,但实际上它并不是。从对象中序列化出来的东西最终变成了一个字符串。在属性是 Double 类型的情况下,我们会得到
<Value xsi:type="xsd:string">3</Value>
当一个 System.Drawing.Rectangle,产生了 "3"
的结果。
<Value xsi:type="xsd:string">{X=145,Y=114,Width=160,Height=75}</Value>
产生的结果为 "{X=145,Y=114,Width=160,Height=75}"
那么有没有一种方法可以直接将值类型或对象的Xml表示转换为.NET等效类型呢?
(或者我必须使用Reflection/System.Activator手动实例化对象并转换(对于基元类型),或解析属性和值(对于非基元类型)?)
XmlElement
属性多次注释Value
属性,指定正确的类型,例如:[XmlElement(type=typeof(string)),XmlElement(type=typeof(System.Drawing.Rectangle))]
,然后使用模式匹配来读取值。 - EldarXmlSerializer
只支持在派生类型被静态预声明时进行序列化。要做到这一点,请参见使用XmlSerializer序列化派生类。 - dbcColor
,但我可以接受它不可序列化的事实,因为我有一个 Xml 元素,可以容纳任何可序列化类型,如基元和诸如矩形、点等美好的东西,以及其他未来可能起作用的东西。我的代码库有许多不同类型的属性仪器,我希望保持开放,支持任何这些属性,只要它们是 xmlserializable 的,而无需重新编译。我知道一些类型是不可 xmlserializable 的,例如一些(全部?)窗体控件,我可以不用它们... - djv