C# Xml反序列化为System.Type
我正在尝试反序列化一段XML,该XML将.NET类型指定为C# Xml反序列化为System.Type,c#,xml,xml-deserialization,C#,Xml,Xml Deserialization,我正在尝试反序列化一段XML,该XML将.NET类型指定为System.type的实例。给定 <SomeObject> <SomeType>System.String, mscorlib</SomeType> </SomeObject> 令人恼火的是,我以前确实做过这件事,但没有访问源代码,也记不起来,事实证明,如果给定所需的关键字(“Xml”、“反序列化”、“类型”几乎提供了所有信息),那么研究解决方案是非常困难的 根据我的记忆,我在Som
System.type
的实例。给定
<SomeObject>
<SomeType>System.String, mscorlib</SomeType>
</SomeObject>
令人恼火的是,我以前确实做过这件事,但没有访问源代码,也记不起来,事实证明,如果给定所需的关键字(“Xml”、“反序列化”、“类型”几乎提供了所有信息),那么研究解决方案是非常困难的
根据我的记忆,我在
SomeType
属性上添加了一个简单的属性
,然后XmlSerializer
从那里开始处理它。有人知道我需要什么属性或者我记错了什么属性吗?如果您不想拥有类型为string
(此问题的常见解决方案)的附加属性,您可以像这样使用代理类:
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);
}
}
这个类所做的只是将类型程序集限定名存储为字符串,并定义从类型到类型的隐式转换运算符。然后您只需要使用xmlement
属性修饰SomeType
,并指定它的Type
是XmlTypeProxy
:
public class SomeObject {
[XmlElement(Type = typeof(XmlTypeProxy))]
public Type SomeType { get; set; }
}
现在,由于存在从Type
到XmlTypeProxy
(反之亦然)的隐式转换,序列化和反序列化都将按预期工作。而我已将的答案标记为正确(如果您反序列化多个Type
属性),实际上,我最终采用了一种更简单的方法
根据答案,我修改了SomeObject
to
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; }
}
虽然单个属性的代码较短,但它不如公认的答案那么健壮。我在这里记录有两种方法可以帮助其他人。在这种情况下,只需使用字符串。@jdweng,如果我找不到更好的方法,仍然是一个选项,但我非常确定有一个.NET属性可以用来自动处理它。它类似于这个问题吗@简单,非常接近。你知道这是否被包装成一个专用的属性
?在没有代理类的情况下应该可以做到这一点(不过,如果我找不到任何东西,我会将其标记为已接受)。例如,在设置自定义配置节时(当我以前这样做时),您可以直接将配置元素反序列化为类型
,而无需中介XmlTypeProxy
。在.NET内部的某个地方,有一种方法可以一步完成这项工作……自定义配置部分与纯XmlSerializer不同,其中涉及的代码要多得多。你没有错,但我觉得还有一种方法。“自定义配置节”方法可以通过[TypeConverter(typeof(TypeNameConverter))]
实现这一点,但是XmlSerializer
没有使用这一点-链中缺少一部分…@DiskJunky XmlSerializer的设计非常糟糕(至少按照现代标准),有很多事情它不能做,或者很难做。
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; }
}