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

来源:互联网 发布:java 两种状态的按钮 编辑:程序博客网 时间:2024/06/04 19:59

3、使用XmlSerializer进行串行化

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

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

[csharp] view plain copy
  1. [Serializable()]  
  2.     public class XmlSerialize  
  3.     {  
  4.         private int id;  
  5.         public int ID  
  6.         {  
  7.             get { return id; }  
  8.             set { id = value; }  
  9.         }  
  10.   
  11.         private string name;  
  12.         public string Name  
  13.         {  
  14.             get { return name; }  
  15.             set { name = value; }  
  16.         }  
  17.   
  18.         private SexType sex;  
  19.         public SexType Sex  
  20.         {  
  21.             get { return sex; }  
  22.             set { sex = value; }  
  23.         }  
  24.   
  25.         private List<string> listStr;  
  26.         public List<string> ListStr  
  27.         {  
  28.             get { return listStr; }  
  29.             set { listStr = value; }  
  30.         }  
  31.   
  32.   
  33.         private List<Item> listItem;  
  34.         [XmlArrayItem(typeof(Item)), XmlArrayItem(typeof(ItemSub))]  
  35.         public List<Item> ListItem  
  36.         {  
  37.             get { return listItem; }  
  38.             set { listItem = value; }  
  39.         }  
  40.   
  41.         private Item[] arrayItem;  
  42.   
  43.         [XmlArrayItem(ElementName = "Item",  
  44.    IsNullable = true,  
  45.    Type = typeof(Item),  
  46.    Namespace = "http://www.cpandl.com"),  
  47.    XmlArrayItem(ElementName = "BookItem",  
  48.    IsNullable = true,  
  49.    Type = typeof(ItemSub),  
  50.    Namespace = "http://www.cohowinery.com")]  
  51.         [XmlArray]  
  52.         public Item[] ArrayItem  
  53.         {  
  54.             get { return arrayItem; }  
  55.             set { arrayItem = value; }  
  56.         }  
  57.   
  58.         private ListBuffer buffer = new ListBuffer(); // 这种封装列表列,xml无法序列化  
  59.         public ListBuffer Buffer  
  60.         {  
  61.             get { return buffer; }  
  62.             set { buffer = value; }  
  63.         }  
  64.   
  65.         private ListBufferSub bufferSub = new ListBufferSub();  
  66.         public ListBufferSub BufferSub  
  67.         {  
  68.             get { return bufferSub; }  
  69.             set { bufferSub = value; }  
  70.         }  
  71.   
  72.         //private List<ListBuffer> listBuffer;  
  73.         //public List<ListBuffer> ListBuffer  
  74.         //{  
  75.         //    get { return listBuffer; }  
  76.         //    set { listBuffer = value; }  
  77.         //}  
  78.     }  
  79.   
  80.     public sealed class ConfigurationManagerXmlSerialize  
  81.     {  
  82.         private static string path = System.Windows.Forms.Application.StartupPath + "\\XmlSerialize.xml";  
  83.   
  84.         public static XmlSerialize Get()  
  85.         {  
  86.             if (!File.Exists(path))  
  87.                 return null;  
  88.   
  89.             XmlSerializer b = new XmlSerializer(typeof(XmlSerialize));  
  90.             using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))  
  91.             {  
  92.                 return (XmlSerialize)b.Deserialize(fs);  
  93.             }  
  94.         }  
  95.   
  96.         public static void Set(XmlSerialize hr)  
  97.         {  
  98.             XmlSerializer b = new XmlSerializer(typeof(XmlSerialize));  
  99.             using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))  
  100.             {  
  101.                 b.Serialize(fs, hr);  
  102.             }  
  103.         }  
  104.     }  

备注:

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序列化不便的话,可考虑用二进制序列化
在很多情况下,二进制序列化对对象的序列化信息更加完整、准确。