C# 串行化与反串行化--使用XmlSerializer进行串行化

3、使用XmlSerializer进行串行化

串行化的文件是xml格式,能串行泛型,继承等关系对象,但是不能串行只包含私有成员的对象,有一定的限制,比BinaryFormatter弱一点,比Soap强一点。其中它串行化继承关系对象时,需要使用xmlarrayitem特性进行特殊标记。

对象中包含的所有类都必须有默认构造函数,否则反射失败。

[Serializable()]
    public class XmlSerialize
    {
        private int id;
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private SexType sex;
        public SexType Sex
        {
            get { return sex; }
            set { sex = value; }
        }

        private List<string> listStr;
        public List<string> ListStr
        {
            get { return listStr; }
            set { listStr = value; }
        }


        private List<Item> listItem;
        [XmlArrayItem(typeof(Item)), XmlArrayItem(typeof(ItemSub))]
        public List<Item> ListItem
        {
            get { return listItem; }
            set { listItem = value; }
        }

        private Item[] arrayItem;

        [XmlArrayItem(ElementName = "Item",
   IsNullable = true,
   Type = typeof(Item),
   Namespace = "http://www.cpandl.com"),
   XmlArrayItem(ElementName = "BookItem",
   IsNullable = true,
   Type = typeof(ItemSub),
   Namespace = "http://www.cohowinery.com")]
        [XmlArray]
        public Item[] ArrayItem
        {
            get { return arrayItem; }
            set { arrayItem = value; }
        }

        private ListBuffer buffer = new ListBuffer(); // 这种封装列表列,xml无法序列化
        public ListBuffer Buffer
        {
            get { return buffer; }
            set { buffer = value; }
        }

        private ListBufferSub bufferSub = new ListBufferSub();
        public ListBufferSub BufferSub
        {
            get { return bufferSub; }
            set { bufferSub = value; }
        }

        //private List<ListBuffer> listBuffer;
        //public List<ListBuffer> ListBuffer
        //{
        //    get { return listBuffer; }
        //    set { listBuffer = value; }
        //}
    }

    public sealed class ConfigurationManagerXmlSerialize
    {
        private static string path = System.Windows.Forms.Application.StartupPath + "\\XmlSerialize.xml";

        public static XmlSerialize Get()
        {
            if (!File.Exists(path))
                return null;

            XmlSerializer b = new XmlSerializer(typeof(XmlSerialize));
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                return (XmlSerialize)b.Deserialize(fs);
            }
        }

        public static void Set(XmlSerialize hr)
        {
            XmlSerializer b = new XmlSerializer(typeof(XmlSerialize));
            using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                b.Serialize(fs, hr);
            }
        }
    }

备注:

xml序列化也能序列化很多类,但是对于太过复杂的类,还是无能为力。

xml反序列化需要类以及类中包含的所有对象都有默认构造函数,否则序列化异常。

xml序列化在处理包含集合成员时,如果集合中元素包含继承关系,那么需要在集合成员上使用特性XmlArrayItem,用了标记此集合中包含哪几种具体类型。


xml序列化有如下限制:
    (1)需序列化的字段必须是公共的(public)
    (2)需要序列化的类都必须有一个无参的构造函数
    (3)枚举变量可序列化为字符串,无需用[XmlInclude]
    (4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该规则递归作用到子元素
        如导出ArrayList对象,若其成员是自定义的,需预包含处理:
        using System.Xml.Serialization;
        [XmlInclude(typeof(自定义类))]
    (5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
        也就是说:针对值类型(如结构体)该功能是实效的
        若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
        若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
    (6)真正无法XML序列化的情况
        某些类就是无法XML序列化的(即使使用了[XmlInclude])
            IDictionary(如HashTable)
            System.Drawing.Color
            System.Drawing.Font
            SecurityAttribute声明
        父类对象赋予子类对象值的情况
        对象间循环引用
    (7)对于无法XML序列化的对象,可考虑
        使用自定义xml序列化(实现IXmlSerializable接口)
        实现IDictionary的类,可考虑(1)用其它集合类替代;(2)用类封装之,并提供Add和this函数
        某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数 
        过于复杂的对象用xml序列化不便的话,可考虑用二进制序列化

在很多情况下,二进制序列化对对象的序列化信息更加完整、准确。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值