【发布时间】:2015-10-16 06:09:45
【问题描述】:
我有一个接口IInput,它阻止 XmlSerializer 对类进行本机序列化(因为它不喜欢接口)。我发现了一个 hack/workaround,它试图在反序列化时创建底层实现,然后将其转换回接口。反序列化器知道底层实现,因为它被编码为属性AssemblyQualifiedName
为了利用这种技术,我必须实现 IXmlSerializable,但只有 1 个属性真正需要帮助(IInput Input),我希望所有其他属性都像正常一样.这是我的课,它按预期工作 但似乎是一种非常混乱的方式来获取普通 XMLserializer 可以序列化以符合 IXmlSerialable 接口的类型。
是否有某种“本机序列化除 x 之外的所有属性”?如果不是,我可以使这个更易读和/或更少复制和粘贴的一种方法
public class JobInput : IJobInput, IXmlSerializable
{
public int AgencyId { get; set; }
public Guid ExternalId { get; set; }
public string Requester { get; set; }
public IInput Input { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
reader.ReadStartElement();
if (!reader.IsEmptyElement)
{
reader.ReadStartElement("AgencyId");
var xmlSerializer = new XmlSerializer(AgencyId.GetType());
AgencyId = ((int)xmlSerializer.Deserialize(reader));
reader.ReadEndElement();
reader.ReadStartElement("ExternalId");
xmlSerializer = new XmlSerializer(ExternalId.GetType());
ExternalId = ((Guid)xmlSerializer.Deserialize(reader));
reader.ReadEndElement();
reader.ReadStartElement("Requester");
xmlSerializer = new XmlSerializer(typeof(string));
Requester = ((string)xmlSerializer.Deserialize(reader));
reader.ReadEndElement();
var type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"), true);
reader.ReadStartElement("IInput");
xmlSerializer = new XmlSerializer(type);
Input = ((IInput)xmlSerializer.Deserialize(reader));
reader.ReadEndElement();
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("AgencyId");
var xmlSerializer = new XmlSerializer(AgencyId.GetType());
xmlSerializer.Serialize(writer, AgencyId);
writer.WriteEndElement();
writer.WriteStartElement("ExternalId");
xmlSerializer = new XmlSerializer(ExternalId.GetType());
xmlSerializer.Serialize(writer, ExternalId);
writer.WriteEndElement();
writer.WriteStartElement("Requester");
xmlSerializer = new XmlSerializer(Requester.GetType());
xmlSerializer.Serialize(writer, Requester);
writer.WriteEndElement();
writer.WriteStartElement("IInput");
writer.WriteAttributeString("AssemblyQualifiedName", Input.GetType().AssemblyQualifiedName);
xmlSerializer = new XmlSerializer(Input.GetType());
xmlSerializer.Serialize(writer, Input);
writer.WriteEndElement();
}
}
是否有可能有一个通用函数可以检测所有具体类型的类型并适当地序列化/反序列化。我想 像
public void WriteXml(XmlWriter writer) {
GenericSerialize("AgencyId", AgencyId, writer);
GenericSerialize("ExternalId", ExternalId, writer);
GenericSerialize("Requester", Requester, writer);
writer.WriteStartElement("IInput");
writer.WriteAttributeString("AssemblyQualifiedName", Input.GetType().AssemblyQualifiedName);
xmlSerializer = new XmlSerializer(Input.GetType());
xmlSerializer.Serialize(writer, Input);
writer.WriteEndElement();
}
【问题讨论】:
-
Natively 表示使用
XmlSerialier?使用XmlIgnore。另见this answer,即“隐藏并使用另一个属性”部分。 -
问题不在于如何序列化我的界面(我这样做是正确的),而在于重构代码以使其看起来更好。
-
关键是避免手动进行序列化,然后突然没有什么可改进的。
标签: c# xml serialization xmlserializer