雪山飞狐_lzh 发表于 2010-1-16 11:57:00

可序列化的泛型集合类

经常遇到集合类的序列化和反序列化,所以就有简化的想法,:)
使用Xml序列化时集合类通常被序列化为数组,而忽视掉公共属性,但有时属性是必要了
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace TlsCad.Collections
{
   
    public class SerialList : List
    {
      
      public Action ItemAdded;
      
      public Action ItemRemoving;
      public SerialList()
            : base()
      { }
      public SerialList(IEnumerable lst)
            : base(lst)
      { }
      public virtual void CopyFrom(IEnumerable lst)
      {
            base.AddRange(lst);
            if (ItemAdded != null)
            {
                foreach (T item in lst)
                {
                  ItemAdded(item);
                }
            }
      }
      #region List
      public new virtual void Add(T item)
      {
            base.Add(item);
            if (ItemAdded != null)
            {
                ItemAdded(item);
            }
      }
      public new virtual void AddRange(IEnumerable items)
      {
            base.AddRange(items);
            if (ItemAdded != null)
            {
                foreach (T item in items)
                {
                  ItemAdded(item);
                }
            }
      }
      public new virtual bool Remove(T item)
      {
            if (ItemRemoving != null && this.Contains(item))
            {
                ItemRemoving(item);
            }
            return base.Remove(item);
      }
      public new virtual void RemoveRange(int index, int count)
      {
            if (ItemRemoving != null)
            {
                for (int i = index; i0 && indexReadXml(string path)
      {
            if (File.Exists(path))
            {
                using (XmlTextReader reader = new XmlTextReader(path))
                {
                  reader.Normalization = false;
                  XmlSerializer xs = new XmlSerializer(GetType());
                  SerialList items = ((SerialList)xs.Deserialize(reader));
                  CopyFrom(items);
                  return items;
                }
            }
            return null;
      }
      #endregion
      #region Bin
      class UBinder : SerializationBinder
      {
            public override Type BindToType(string assemblyName, string typeName)
            {
                try
                {
                  return Type.GetType(typeName);
                }
                catch
                {
                  return Assembly.Load(assemblyName).GetType(typeName);
                }
            }
      }
      public virtual void WriteTo(string path)
      {
            using (Stream stream = File.Open(path, FileMode.Create))
            {
                BinaryFormatter bformatter = new BinaryFormatter();
                bformatter.Serialize(stream, this);
            }
      }
      public virtual SerialList ReadFrom(string path)
      {
            if (File.Exists(path))
            {
                using (Stream stream = File.Open(path, FileMode.Open))
                {
                  BinaryFormatter bformatter = new BinaryFormatter();
                  bformatter.Binder = new UBinder();
                  SerialList lst = (SerialList)bformatter.Deserialize(stream);
                  CopyFrom(lst);
                  return lst;
                }
            }
            return null;
      }
      #endregion
    }}

雪山飞狐_lzh 发表于 2010-1-16 11:58:00


using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Linq;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace TlsCad.Collections
{
   
    public class SerialList : SerialList
    {
      public TInfo Info { get; set; }
      public SerialList()
            : base()
      { }
      public SerialList(IEnumerable lst)
            : base(lst)
      { }
      public virtual void CopyFrom(SerialList lst)
      {
            Info = lst.Info;
            base.CopyFrom(lst);
      }
      
      #region Xml
      public new virtual void WriteXml(string path)
      {
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            using (XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("SerialList");
                writer.WriteStartElement("Info");
                XmlSerializer xs = new XmlSerializer(typeof(TInfo));
                xs.Serialize(writer, Info, ns);
                writer.WriteEndElement();
                writer.WriteStartElement("Values");
                xs = new XmlSerializer(typeof(TValue));
                foreach (TValue item in this)
                {
                  xs.Serialize(writer, item, ns);
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.Close();
            }
      }
      public new virtual SerialList ReadXml(string path)
      {
            if (File.Exists(path))
            {
                using (XmlTextReader reader = new XmlTextReader(path))
                {
                  SerialList lst = new SerialList();
                  reader.Normalization = false;
                  reader.ReadToDescendant("Info");
                  reader.Read();
                  XmlSerializer xs = new XmlSerializer(typeof(TInfo));
                  lst.Info = (TInfo)xs.Deserialize(reader);
                  reader.Read();
                  reader.Read();
                  xs = new XmlSerializer(typeof(TValue));
                  while (reader.NodeType != XmlNodeType.EndElement)
                  {
                        TValue item = (TValue)xs.Deserialize(reader);
                        if (item != null)
                        {
                            lst.Add(item);
                        }
                  };
                  reader.Close();
                  CopyFrom(lst);
                  return lst;
                }
            }
            return null;
      }
      #endregion
      #region Bin
      public new virtual SerialList ReadFrom(string path)
      {
            SerialList lst =
                (SerialList)base.ReadFrom(path);
            if (lst != null)
            {
                Info = lst.Info;
            }
            return lst;
      }
      #endregion
    }
}

雪山飞狐_lzh 发表于 2010-1-16 11:59:00

测试代码:复制代码命令行输出:
命令: tt
Add a item:key:1,name:lzh;
Add a item:key:2,name:雪山飞狐;
info from Bin:name:TlsCad,des:This is a test
key:1,name:lzh;
key:2,name:雪山飞狐;
info from Xml:name:TlsCad,des:This is a test
key:1,name:lzh;
key:2,name:雪山飞狐;

雪山飞狐_lzh 发表于 2010-1-18 15:15:00

附上使用该类生成的xml文档(NetAutoLoad中使用的初始化文件)复制代码

hmxmylove 发表于 2010-6-6 18:34:00

谢谢
页: [1]
查看完整版本: 可序列化的泛型集合类