Xml 反序列化为 System.Type
Xml Deserialize to System.Type
我正在尝试反序列化 XML 的一段,该片段将 .NET 类型指定为 System.Type
的实例。鉴于
<SomeObject>
<SomeType>System.String, mscorlib</SomeType>
</SomeObject>
反序列化为 class;
public class SomeObject
{
public Type SomeType { get; set; }
}
烦人的是,我实际上在前一段时间做过这个但是没有访问源代码并且不记得了,这已经证明很难研究给定所需关键字的解决方案("Xml" , "Deserialize", "Type" 给出了太阳底下的几乎所有东西)。
据我所知,我在 SomeType
属性 上放了一个简单的 Attribute
,XmlSerializer
从那里处理它。有谁知道我需要什么属性还是我记错了?
如果您不想拥有 string
类型的额外 属性(此问题的通常解决方案)- 您可以像这样使用代理 class:
public class XmlTypeProxy : IXmlSerializable {
private string _typeName;
public XmlTypeProxy() {
}
public XmlTypeProxy(string typeName) {
_typeName = typeName;
}
public XmlSchema GetSchema() {
return null;
}
public void ReadXml(XmlReader reader) {
_typeName = reader.ReadString();
}
public void WriteXml(XmlWriter writer) {
writer.WriteString(_typeName);
}
public static implicit operator Type(XmlTypeProxy self) {
return Type.GetType(self._typeName);
}
public static implicit operator XmlTypeProxy(Type self) {
return new XmlTypeProxy(self.AssemblyQualifiedName);
}
}
这个 class 所做的只是将类型程序集限定名称存储为字符串,并定义从和到 Type
类型的隐式转换运算符。然后你只需要用 XmlElement
属性修饰 SomeType
并指定它的 Type
是 XmlTypeProxy
:
public class SomeObject {
[XmlElement(Type = typeof(XmlTypeProxy))]
public Type SomeType { get; set; }
}
现在,因为存在从 Type
到 XmlTypeProxy
的隐式转换(反之亦然)- 序列化和反序列化都将按预期工作。
虽然我已将 Evk 的答案标记为正确(如果您要反序列化多个 Type
属性),我实际上采用了一种更简单的方法最后。
根据this的回答,我将SomeObject
修改为;
public class SomeObject
{
public string SomeTypeName
{
get { return SomeType.AssemblyQualifiedName; }
set
{
var converter = new TypeNameConverter();
SomeType = (Type)converter.ConvertFrom(value);
}
}
[XmlIgnore]
public Type SomeType { get; set; }
}
虽然单个 属性 的代码较短,但不如公认的答案那么可靠。我在这里记录这两种方法可能对其他人有帮助。
我正在尝试反序列化 XML 的一段,该片段将 .NET 类型指定为 System.Type
的实例。鉴于
<SomeObject>
<SomeType>System.String, mscorlib</SomeType>
</SomeObject>
反序列化为 class;
public class SomeObject
{
public Type SomeType { get; set; }
}
烦人的是,我实际上在前一段时间做过这个但是没有访问源代码并且不记得了,这已经证明很难研究给定所需关键字的解决方案("Xml" , "Deserialize", "Type" 给出了太阳底下的几乎所有东西)。
据我所知,我在 SomeType
属性 上放了一个简单的 Attribute
,XmlSerializer
从那里处理它。有谁知道我需要什么属性还是我记错了?
如果您不想拥有 string
类型的额外 属性(此问题的通常解决方案)- 您可以像这样使用代理 class:
public class XmlTypeProxy : IXmlSerializable {
private string _typeName;
public XmlTypeProxy() {
}
public XmlTypeProxy(string typeName) {
_typeName = typeName;
}
public XmlSchema GetSchema() {
return null;
}
public void ReadXml(XmlReader reader) {
_typeName = reader.ReadString();
}
public void WriteXml(XmlWriter writer) {
writer.WriteString(_typeName);
}
public static implicit operator Type(XmlTypeProxy self) {
return Type.GetType(self._typeName);
}
public static implicit operator XmlTypeProxy(Type self) {
return new XmlTypeProxy(self.AssemblyQualifiedName);
}
}
这个 class 所做的只是将类型程序集限定名称存储为字符串,并定义从和到 Type
类型的隐式转换运算符。然后你只需要用 XmlElement
属性修饰 SomeType
并指定它的 Type
是 XmlTypeProxy
:
public class SomeObject {
[XmlElement(Type = typeof(XmlTypeProxy))]
public Type SomeType { get; set; }
}
现在,因为存在从 Type
到 XmlTypeProxy
的隐式转换(反之亦然)- 序列化和反序列化都将按预期工作。
虽然我已将 Evk 的答案标记为正确(如果您要反序列化多个 Type
属性),我实际上采用了一种更简单的方法最后。
根据this的回答,我将SomeObject
修改为;
public class SomeObject
{
public string SomeTypeName
{
get { return SomeType.AssemblyQualifiedName; }
set
{
var converter = new TypeNameConverter();
SomeType = (Type)converter.ConvertFrom(value);
}
}
[XmlIgnore]
public Type SomeType { get; set; }
}
虽然单个 属性 的代码较短,但不如公认的答案那么可靠。我在这里记录这两种方法可能对其他人有帮助。