您的位置:首页 > 编程语言 > C#

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

2013-04-26 15:24 330 查看
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序列化不便的话,可考虑用二进制序列化

在很多情况下,二进制序列化对对象的序列化信息更加完整、准确。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: