let say i want to represent arithmetic expression using xml:
<?xml version="1.0" encoding="utf-8" ?><expr><add><num>10</num><num>20</num></add></expr>
and here is my classes to represent this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { public abstract class Evaluable { public abstract int Eval(); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; namespace Test { [Serializable] [XmlRoot("expr")] public class Expr { [XmlElement] public Evaluable Evaluable { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; namespace Test { [Serializable] [XmlRoot("add")] [XmlType("add")] public class Add : Evaluable { [XmlElement] public List<Evaluable> Elems { get; set; } public override int Eval() { return Elems.Select(e => e.Eval()).Sum(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; namespace Test { [Serializable] [XmlRoot("num")] [XmlType("num")] public class Num : Evaluable { [XmlText] public int Val { get; set; } public override int Eval() { return Val; } } }
but it doesn't work, and it's reasonable, since Serializer doesn't know any thing about the subclass. but how to make it work?
here is my deserialization code:
var serializer = new XmlSerializer(typeof(Expr), new[] { typeof(Add), typeof(Num) }); Expr expr = null; using (var file = new StreamReader("expr.xml")) { expr = serializer.Deserialize(file) as Expr; }