XmlSerializer使用小结

  1.       问题背景:

写了一个类(嵌套了很多其它类)来保存UI(可编辑)的现场数据。现在有一个需求,就是在UI程序关闭时将这些数据保存起来,等下次UI打开时自动加载这些保存的数据,即恢复UI上次关闭时的状态。即需要一个序列化和反序列化的工具,至于序列化成什么格式不关注,只要反序列化时能恢复当初被序列化对象的所有数据即可。于是考虑用System.Xml.Serialization.XmlSerializer来做这件事情。在使用过程这中遇到一些问题,特将这些问题的解决过程记录下来,以备以后再用时参考。

 

2.       问题描述:

1)         假设想要序列化的类想要序列化的类A包含一个B类对象,和一个C类对象List。其中C是抽象类,有C1C2两个具体类实现了它。如下图所示:    

 

 

2)         代码如下: 

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;

namespace Spacer_Robot
{
    
public class XmlSerilizeTest
    {
        
static void Main(string[] args)
        {
            A a 
= new A();
            B b 
= new B(3);
            a.B 
= b;
            List
<C> cList = new List<C>();

            C1 c1 
= new C1();
            c1.CInt 
= 1;
            cList.Add(c1);

            C2 c2 
= new C2();
            c2.CInt 
= 2;
            cList.Add(c2);

            a.CList 
= cList;

            SerilizeAnObject(a, 
"test.xml");           
        }

        
private static void SerilizeAnObject(object obj, string path)
        {
            System.IO.FileStream stream 
= new FileStream(path, FileMode.Create);
            
try
            {
                System.Xml.Serialization.XmlSerializer serializer 
=
                    
new System.Xml.Serialization.XmlSerializer(obj.GetType());
                serializer.Serialize(stream, obj);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"SerilizeAnObject Exception: {0}", ex.Message);
            }
            
finally
            {
                stream.Close();
                stream.Dispose();
            }
        }

        
private static object DeserilizeAnObject(Type type, string path)
        {
            
object obj = null;
            System.IO.FileStream stream 
= new FileStream(path, FileMode.Open);
            
try
            {
                System.Xml.XmlReader reader 
= new XmlTextReader(stream);
                System.Xml.Serialization.XmlSerializer serializer 
=
                    
new System.Xml.Serialization.XmlSerializer(type);
                obj 
= serializer.Deserialize(reader);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"DeserilizeAnObject Exception: {0}", ex.Message);
            }
            
finally
            {
                stream.Close();
                stream.Dispose();
            }

            
return obj;
        }
    }

    
public class A
    {
        
public B B
        {
            
get;
            
set;
        }

        
public List<C> CList
        {
            
get;
            
set;
        }
    }

    
public class B
    {       
        
public B(int value)
        {
            bInt 
= value;
        }

        
int bInt;
        
public int BInt
        {
            
get { return bInt; }
            
set { bInt = value; }
        }
    }
       
    
public abstract class C
    {
    }

    
public class C1 : C
    {
        
public int CInt
        {
            
get;
            
set;
        }
    }

    
public class C2 : C
    {
        
public int CInt
        {
            
get;
            
set;
        }
    }
}

 

3)         上述代码存在三个问题:

a)         ACList成员无法被序列化。

b)         B无法被序列化。

c)         C1C2无法被序列化。

 

3.       原因分析和解决办法:

1)       CList成员无法被序列化:System.Xml.Serialization.XmlSerializer无法序列化List<>,改用数组。

2)       B无法被无法被序列化:对每个需要被序列化的类,要么没有提供构造函数,如果提供了,就必须同时提供一个无参构造函数。所以需要类B提供无参构造函数。

3)       C1C2无法被序列化:要想序列化以其抽象类的形式出现的具体类,必须在抽象类定义的地方用AttributeSystem.Xml.Serialization.XmlInclude来指明该具体类。

4)       修改后的代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;

namespace Spacer_Robot
{
    
public class XmlSerilizeTest
    {
        
static void Main(string[] args)
        {
            A a 
= new A();
            B b 
= new B(3);
            a.B 
= b;
            List
<C> cList = new List<C>();

            C1 c1 
= new C1();
            c1.CInt 
= 1;
            cList.Add(c1);

            C2 c2 
= new C2();
            c2.CInt 
= 2;
            cList.Add(c2);

            a.CArray 
= cList.ToArray();

            SerilizeAnObject(a, 
"test.xml");

            A a1 
= new A();
            a1 
= (A)DeserilizeAnObject(a1.GetType(), "test.xml");
            Console.WriteLine(
"A.B.BInt = {0}", a1.B.BInt);
            Console.WriteLine(
"A.CArray.C1.CInt = {0}", ((C1)a1.CArray[0]).CInt);
            Console.WriteLine(
"A.CArray.C2.CInt = {0}", ((C2)a1.CArray[1]).CInt);
        }

        
private static void SerilizeAnObject(object obj, string path)
        {
            System.IO.FileStream stream 
= new FileStream(path, FileMode.Create);
            
try
            {
                System.Xml.Serialization.XmlSerializer serializer 
=
                    
new System.Xml.Serialization.XmlSerializer(obj.GetType());
                serializer.Serialize(stream, obj);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"SerilizeAnObject Exception: {0}", ex.Message);
            }
            
finally
            {
                stream.Close();
                stream.Dispose();
            }
        }

        
private static object DeserilizeAnObject(Type type, string path)
        {
            
object obj = null;
            System.IO.FileStream stream 
= new FileStream(path, FileMode.Open);
            
try
            {
                System.Xml.XmlReader reader 
= new XmlTextReader(stream);
                System.Xml.Serialization.XmlSerializer serializer 
=
                    
new System.Xml.Serialization.XmlSerializer(type);
                obj 
= serializer.Deserialize(reader);
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"DeserilizeAnObject Exception: {0}", ex.Message);
            }
            
finally
            {
                stream.Close();
                stream.Dispose();
            }

            
return obj;
        }
    }

    
public class A
    {
        
public B B
        {
            
get;
            
set;
        }

        
public C[] CArray
        {
            
get;
            
set;
        }
    }

    
public class B
    {
        
public B()
        {
        }

        
public B(int value)
        {
            bInt 
= value;
        }

        
int bInt;
        
public int BInt
        {
            
get { return bInt; }
            
set { bInt = value; }
        }
    }

    [System.Xml.Serialization.XmlInclude(
typeof(C1)),
     System.Xml.Serialization.XmlInclude(
typeof(C2))]
    
public abstract class C
    {
    }

    
public class C1 : C
    {
        
public int CInt
        {
            
get;
            
set;
        }
    }

    
public class C2 : C
    {
        
public int CInt
        {
            
get;
            
set;
        }
    }
}

 

4.       其它:

MSDN中对XmlSerializer使用的帮助链接为:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

 

 

转载于:https://www.cnblogs.com/zsh_robot/articles/1323949.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值