序列化和反序列化
/// <summary>
/// 主程序
/// </summary>
public class Cmain
{
string ls_xml;
/// <summary>
/// 序列化
/// </summary>
private void button3_Click()
{
BB b = new BB(1);
AA a = new AA(b);
ls_xml = SerializeToXML<AA>(a);
}
/// <summary>
/// 反序列化
/// </summary>
private void button4_Click()
{
AA b = (AA)DeSerializeFromXML<AA>(ls_xml);
int i;
i = 0;
}
/// <summary>
/// 序列化方法
/// </summary>
/// <param name="lo_obj"></param>
/// <returns></returns>
public string SerializeToXML<T>(object lo_obj)
{
try
{
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb);
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, lo_obj);
writer.Close();
return sb.ToString();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 反序列化方法
/// </summary>
/// <param name="ls_xml"></param>
/// <returns></returns>
public object DeSerializeFromXML<T>(string ls_xml)
{
try
{
StringReader strReader = new StringReader(ls_xml);
XmlReader xmlReader = XmlReader.Create(strReader);
XmlSerializer serialize = new XmlSerializer(typeof(T));
object obj = serialize.Deserialize(xmlReader);
return obj;
}
catch (Exception ex)
{
throw ex;
}
}
}
public class AA
{
private List<BB> l_list;
public List<BB> L_list
{
get { return this.l_list; }
set { this.l_list = value; }
}
public AA(BB a)
{
this.l_list = new List<BB>();
this.l_list.Add(a);
}
public AA()
{
}
}
public class BB
{
private List<string> l_list;
public List<string> L_list
{
get { return this.l_list; }
set { this.l_list = value; }
}
public BB(int a)
{
this.l_list = new List<string>();
this.l_list.Add(a.ToString());
}
public BB()
{
}
}
总结:
List<obj>和ArrayList可以序列化,但HastTable不可以序列化,List<obj>中的Obj如果包含Hashtable或者不可以
序列化的对象,则包含List<obj>的对象就不可以序列化,如上例中把BB.List<string>修改为List<Hashtable>,则AA在序列化时就会出错。
另外 接口也不能序列化例如List<Interface>也是不能序列化的,遇到这种情况可以把接口修改为抽象类,同时在抽象类上添加
[XmlInclude]属性,列如:[XmlInclude(typeof(srvdll.ConcreteCommand.CreateFile)),
XmlInclude(typeof(srvdll.ConcreteCommand.AppendFile)),
XmlInclude(typeof(srvdll.ConcreteCommand.GetDataSetCommand)),
XmlInclude(typeof(srvdll.ConcreteCommand.sqlCommand))],
最后需要注意一点,自己写的类要想序列化必须有默认构造函数(不带参数的构造函数)。
下面的这种情况下Obj_body可能包括有TaskList,CommandList,所以要用XmlInclude属性,否则在序列化时可能出错!
[XmlInclude(typeof(srvdll.TaskList)),
XmlInclude(typeof(srvdll.CommandList))]
public class CommunicationMessage
{
string str_head;
/// <summary>
/// 消息头
/// </summary>
public string Str_head
{
get { return this.str_head; }
set { this.str_head = value; }
}
object obj_body;
/// <summary>
/// 消息主体
/// </summary>
public object Obj_body
{
get { return this.obj_body; }
set { this.obj_body = value; }
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="head"></param>
/// <param name="obj"></param>
public CommunicationMessage(string head, object obj)
{
this.str_head = head;
this.obj_body = obj;
}
/// <summary>
/// 序列化构造器
/// </summary>
public CommunicationMessage()
{
}
}
上例:里面的obj_body 如果传入的是DataSet或者是类型化的数据集在序列化时会提示("类型 System.Data.DataSet 不能用在此上下文中。要将 System.Data.DataSet 用作参数、返回类型或者类或结构的成员,该参数、返回类型或成员必须声明为类型 System.Data.DataSet(它不能是对象)。类型 System.Data.DataSet 的对象不能用在非类型化的集合如 ArrayList 中。").