如何正确地为ICollection <t>实现IXmlSerializable,其中T是一个抽象类?</t>

时间:2013-12-11 00:57:27

标签: abstract-class icollection ixmlserializable

我正在尝试在T的集合中实现IXmlSerializable接口,其中T是一个抽象类。 我的情况是:

  1. 我有一个抽象类BaseClass,它实现了IXmlSerializable
  2. 两个派生的clases(Deriv01,Deriv02),它继承自BaseClass 并重写方法以正确实现WriteXml和 的ReadXml
  3. BaseClass(BaseClassCollection)的集合,它是一个 ICollection并实现了IXmlSerializable
  4. 该集合的序列化工作正常,但我坚持反序列化,我不知道如何实现它,我希望你的帮助。

    这是我的实施:

    [XmlInclude(typeof(Deriv01))]
    [XmlInclude(typeof(Deriv02))]
    [XmlType("base")]
    public abstract class BaseClass : IXmlSerializable
    {
        private int _a;
        private string _b;
    
        public int A
        {
            get { return this._a; }
        }
        public string B
        {
            get { return this._b; }
        }
    
        protected BaseClass()
        {
            this._b = string.Empty;
        }
        protected BaseClass(int a, string b)
        {
            this._a = a;
            this._b = !string.IsNullOrEmpty(b) ? b : string.Empty;
        }
    
        protected virtual void WriteXmlAttributes(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            writer.WriteAttributeString("a", XmlConvert.ToString(this._a));
        }
        protected virtual void WriteXmlElements(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            writer.WriteStartElement("b");
            writer.WriteString(this._b);
            writer.WriteEndElement();
        }
        protected virtual void ReadXmlAttributes(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
            int a;
            this._a = int.TryParse(reader["a"], out a) ? a : 0;
        }
        protected virtual void ReadXmlElements(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
    
            reader.Read();
            if (!reader.IsStartElement("b")) return;
            this._b = reader.ReadString();
            reader.ReadEndElement();
        }
    
        #region Implementation of IXmlSerializable
        public XmlSchema GetSchema()
        {
            return null;
        }
        public void ReadXml(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
    
            ReadXmlAttributes(reader);
            ReadXmlElements(reader);
        }
        public void WriteXml(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            WriteXmlAttributes(writer);
            WriteXmlElements(writer);
        }
        #endregion
    }
    
    [XmlType("deriv01")]
    public class Deriv01 : BaseClass
    {
        private int _c;
    
        public int C
        {
            get { return this._c; }
        }
    
        public Deriv01()
        { }
        public Deriv01(int a, string b, int c)
            : base(a, b)
        {
            this._c = c;
        }
    
        protected override void WriteXmlAttributes(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            base.WriteXmlAttributes(writer);
            writer.WriteAttributeString("c", XmlConvert.ToString(this._c));
    
            writer.WriteAttributeString("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance", "deriv01");
        }
        protected override void ReadXmlAttributes(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
            base.ReadXmlAttributes(reader);
            int c;
            this._c = int.TryParse(reader["c"], out c) ? c : 0;
        }
    }
    
    [XmlType("deriv02")]
    public class Deriv02 : BaseClass
    {
        private int _d;
    
        public int D
        {
            get { return this._d; }
        }
    
        public Deriv02()
        {
        }
        public Deriv02(int a, string b, int d)
            : base(a, b)
        {
            this._d = d;
        }
        protected override void WriteXmlElements(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            base.WriteXmlElements(writer);
            writer.WriteElementString("d", XmlConvert.ToString(this._d));
        }
        protected override void ReadXmlElements(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
            base.ReadXmlElements(reader);
            int d;
            if (!reader.IsStartElement("d")) return;
            this._d = int.TryParse(reader.ReadString(), out d) ? d : 0;
            reader.ReadEndElement();
        }
        protected override void WriteXmlAttributes(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            base.WriteXmlAttributes(writer);
            writer.WriteAttributeString("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance", "deriv02");
        }
    }
    
    [XmlRoot("elementos")]
    public class BaseClassCollection : ICollection<BaseClass>, IXmlSerializable
    {
        private List<BaseClass> _elementos = new List<BaseClass>();
    
        public BaseClass this[int index]
        {
            get { return this._elementos[index]; }
        }
    
        public BaseClassCollection()
        { }
    
        #region Implementation of ICollection<BaseClass>
        public void Add(BaseClass item)
        {
            if (this._elementos.Contains(item)) return;
            this._elementos.Add(item);
        }
        public void Clear()
        {
            this._elementos.Clear();
        }
        public bool Contains(BaseClass item)
        {
            return this._elementos.Contains(item);
        }
        public void CopyTo(BaseClass[] array, int arrayIndex)
        {
            this._elementos.CopyTo(array, arrayIndex);
        }
        public bool Remove(BaseClass item)
        {
            return this._elementos.Remove(item);
        }
        public int Count
        {
            get { return this._elementos.Count; }
        }
        public bool IsReadOnly
        {
            get { return false; }
        }
        #endregion
    
        #region Implementation of IEnumerable
        public IEnumerator<BaseClass> GetEnumerator()
        {
            foreach (BaseClass elemento in this._elementos)
            {
                yield return elemento;
            }
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion
    
        #region Implementation of IXmlSerializable
        public XmlSchema GetSchema()
        {
            return null;
        }
        public void ReadXml(XmlReader reader)
        {
            if (reader == null) throw new ArgumentNullException("reader");
    
            XmlSerializer inner = new XmlSerializer(typeof(BaseClassCollection));
            reader.Read();
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                //This line don't work
                BaseClass item = (BaseClass) inner.Deserialize(reader);
                this._elementos.Add(item);
            }
            reader.ReadEndElement();
        }
        public void WriteXml(XmlWriter writer)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
            writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
    
            writer.WriteAttributeString("cont", XmlConvert.ToString(this._elementos.Count));
    
            foreach(BaseClass item in this._elementos)
            {
                writer.WriteStartElement("elemento");
                item.WriteXml(writer);
                writer.WriteEndElement();
            }
        }
        #endregion
    }
    
    
    public void ReadXml(XmlReader reader)
    {
        if (reader == null) throw new ArgumentNullException("reader");
    
        BaseClass item = null;
        reader.Read();
        while (reader.NodeType != XmlNodeType.EndElement)
        {
           string type = reader["type", "http://www.w3.org/2001/XMLSchema-instance"];
           switch (type)
           {
               case "deriv01":
                   item = new Deriv01();
                   break;
               case "deriv02":
                   item = new Deriv02();
                   break;
           }
           if (item == null) continue;
           item.ReadXml(reader);
           this._elementos.Add(item);
           reader.ReadEndElement();
       }
       reader.ReadEndElement();
    } 
    

0 个答案:

没有答案