我正在尝试序列化以下类层次结构:
public class Control
{
public virtual string Name {get; set;}
public virtual string Type {get; set;}
public virtual string Text { get; set; }
public virtual SerializableFont Font { get; set; }
private Operation op = new Operation();
public Operation Events { get { return op; } }
}
[System.Xml.Serialization.XmlInclude(typeof(Control))]
public class TextProperties : Control
{
public Label txt;
public TextProperties()
{
}
public override string Type
{
get { return "Text"; }
}
public override string Text
{
get { return txt.Text; }
set
{
txt.Text = value;
}
}
public override SerializableFont Font
{
get { return new SerializableFont(txt.Font); }
set
{
txt.Font = new SerializableFont().Font ;
}
}
}
正如您所看到的,我包括基类但仍然抛出以下异常:
不期望TextProperties类型。使用 XmlInclude或SoapInclude属性指定不是的类型 静态地知道。
答案 0 :(得分:0)
我不确定问题实际上是你的类层次结构本身,似乎没问题。您不需要添加属性。
相反,您可能尝试使用为Control类型的对象创建的XmlSerializer来读取/写入TextProperties类型的对象。这不起作用,您需要使用特定于该类型的序列化程序来序列化/反序列化。
如果在编译时不知道这一点,请尝试创建一个实现IXMLSerializable的包装类。在读取时,此类必须首先读取数据以定义包装对象的类(例如,名为“TypeName”的节点属性)。然后,它必须在运行时为给定类型创建特定的序列化程序,并使用它来加载包装的对象。
编辑:这是一些示例代码,如何完成。您需要自己实现GetTypeByName(例如,遍历所有已加载的程序集或仅将某些字符串“硬连线”到您期望的特定类型)。代码应该足以集成到具有属性“WrappedObject”的类中。
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
var typeName = reader.GetAttribute("TypeName");
reader.ReadStartElement();
var serializer = new XmlSerializer(GetTypeByName(typeName));
WrappedObject = serializer.Deserialize(reader);
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("TypeName", "", GetTypeByName(WrappedObject));
var serializer = new XmlSerializer(typeof(WrappedObject));
serializer.Serialize(writer, WrappedObject);
}
答案 1 :(得分:0)
我认为您需要将属性放在父类之上,如此
[XmlInclude(typeof(ChildClass))]
[Serializable]
public abstract class ParentClass
{
public abstract string Name { get; set; }
}
你在儿童班中
[Serializable]
public class ChildClass: ParentClass
{
}