由于Silverlight精简了很多.net平台的程序集,序列化也变得很麻烦,特别是二进制序列化。以下将介绍两种二进制序列化的解决方案并介 绍其优缺点。

一、使用DataContractSerializer

  • 优点:简单易用
  • 缺点:不能序列化私有成员变量

添加引用:添加一行using System.Runtime.Serialization, 在项目的引用里添加System.Runtime.Serialization程序集。

使用的时候需要在需要序列化的类前加上DataContract属性, 然后在其中需要序列化的成员前加上DataMember属性。具体的使用请看下面代码示例:

 

 1 using  System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Net;
 5 using System.Windows;
 6 using System.Windows.Controls;
 7 using System.Windows.Documents;
 8 using System.Windows.Input;
 9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using System.IO;
13 using System.Runtime.Serialization;
14 
15 namespace SLDataContractSerialization
16 {
17     [DataContract]
18     public class Book
19     {
20         [DataMember]
21         public int ID;
22 
23         [DataMember]
24         public string Name;
25 
26         [DataMember]
27         public string Private;
28 
29         public void SetPrivate(string _Private)
30         {
31             this.Private = _Private;
32         }
33         public string GetPrivate()
34         {
35             return this.Private;
36         }
37     }
38 
39     [DataContract]
40     public class BookList
41     {
42         [DataMember]
43         public string BookListName;
44 
45         [DataMember]
46         public List<Book> MyBookList = new List<Book>();
47     }
48 
49     public partial class MainPage : UserControl
50     {
51        
52         public MainPage()
53         {
54             InitializeComponent();
55 
56             // 实例化三个Book对象
57             Book b1 = new Book { ID = 1001, Name = "Book1" };
58             b1.SetPrivate("Book1 Private");
59             Book b2 = new Book { ID = 1002, Name = "Book2" };
60             b2.SetPrivate("Book2 Private");
61             Book b3 = new Book { ID = 1003, Name = "Book3" };
62             b3.SetPrivate("Book3 Private");
63 
64             // 实例化一个BookList对象,并在MyBookList成员变量中添加刚才实例化的三个Book对象
65             BookList blist = new BookList();
66             blist.BookListName = "BookList1";
67             blist.MyBookList.Add(b1);
68             blist.MyBookList.Add(b2);
69             blist.MyBookList.Add(b3);
70 
71             // 实例化一个DataContractSerializer对象,并设置为BookList类型
72             DataContractSerializer dcs = new DataContractSerializer(typeof(BookList));
73 
74             // 实例化一个MemoryStream来存储序列化后的数据
75             MemoryStream ms = new MemoryStream();
76 
77             // 序列化blist并存到ms中
78             dcs.WriteObject(ms, blist);
79 
80             // 回退到流的开始处
81             ms.Seek(00);
82 
83             // 反序列化并以此实例化一个新的BookList对象
84             BookList blist2 = (BookList)dcs.ReadObject(ms);
85 
86             // 测试
87             tb1.Text = blist2.BookListName;
88             for (int i = 0; i < 3; i++)
89             {
90                 tb2.Text += blist2.MyBookList[i].ID.ToString() + "\n";
91                 tb3.Text += blist2.MyBookList[i].Name + "\n";
92                 tb4.Text += blist2.MyBookList[i].GetPrivate() + "\n";
93             }
94            
95         }
96     }
97 }


 

二、使用自己实现的一个CustomBinarySerializer类

这里使用到了一个老外写的用于序列化的类,你可以到这里详细了解。

  • 优点:可以序列化私有成员变量,字节压缩率高
  • 缺点:需要编写代码实现一个特定接口,不易使用

添加引用:为项目添加这个程序集, 然后添加一个名称空间: using CustomBinarySerializer;
使用的时候,需要让希望序列化的类实现一个ICustomBinarySerializable接口,实现其中的两个方法。具体的使用请看一下代码示例:

 

  1 using  System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Net;
  5 using System.Windows;
  6 using System.Windows.Controls;
  7 using System.Windows.Documents;
  8 using System.Windows.Input;
  9 using System.Windows.Media;
 10 using System.Windows.Media.Animation;
 11 using System.Windows.Shapes;
 12 using System.IO;
 13 using CustomBinarySerializer;
 14 
 15 namespace SerializationSL
 16 {
 17     public class Book: ICustomBinarySerializable
 18     {
 19         public int ID;
 20         public string Name;
 21         private string Private;//测试私有成员变量能否被序列化
 22 
 23         public void SetPrivate(string _Private)
 24         {
 25             this.Private = _Private;
 26         }
 27         public string GetPrivate()
 28         {
 29             return this.Private;
 30         }
 31 
 32         //实现 ICustomBinarySerializable接口的WriteDataTo方法
 33         public void WriteDataTo(BinaryWriter _Writer)
 34         {
 35             _Writer.Write(ID);
 36             _Writer.Write(Name);
 37             _Writer.Write(Private);
 38         }
 39 
 40         //实现 ICustomBinarySerializable接口的SetDataForm方法
 41         public void SetDataFrom(BinaryReader _Reader)
 42         {
 43             ID = _Reader.ReadInt32();
 44             Name = _Reader.ReadString();
 45             Private = _Reader.ReadString();
 46         }
 47     }
 48 
 49     public class BookList : ICustomBinarySerializable
 50     {
 51         public string BookListName;
 52         public List<Book> MyBookList = new List<Book>();
 53 
 54         //实现 ICustomBinarySerializable接口的WriteDataTo方法
 55         public void WriteDataTo(BinaryWriter _Writer)
 56         {
 57             _Writer.Write(BookListName);
 58             foreach (Book b in MyBookList)
 59             {
 60                 _Writer.Write((int)b.ID);
 61                 _Writer.Write((string)b.Name);
 62                 _Writer.Write((string)b.GetPrivate());
 63             }
 64         }
 65 
 66         //实现 ICustomBinarySerializable接口的SetDataForm方法
 67         public void SetDataFrom(BinaryReader _Reader)
 68         {
 69             BookListName = _Reader.ReadString();
 70             while (_Reader.BaseStream.Position < _Reader.BaseStream.Length)
 71             {
 72                 Book b = new Book();
 73                 b.ID = _Reader.ReadInt32();
 74                 b.Name = _Reader.ReadString();
 75                 b.SetPrivate(_Reader.ReadString());
 76                 this.MyBookList.Add(b);
 77             }
 78         }
 79     }
 80 
 81     public partial class MainPage : UserControl
 82     {
 83         public MainPage()
 84         {
 85             InitializeComponent();
 86 
 87             // 实例化三个Book对象
 88             Book b1 = new Book { ID = 1001, Name = "Book1"};
 89             b1.SetPrivate("Book1 Private");
 90             Book b2 = new Book { ID = 1002, Name = "Book2" };
 91             b2.SetPrivate("Book2 Private");
 92             Book b3 = new Book { ID = 1003, Name = "Book3" };
 93             b3.SetPrivate("Book3 Private");
 94 
 95             // 实例化一个BookList对象,并在MyBookList成员变量中添加刚才实例化的三个Book对象
 96             BookList blist = new BookList();
 97             blist.BookListName = "BookList1";
 98             blist.MyBookList.Add(b1);
 99             blist.MyBookList.Add(b2);
100             blist.MyBookList.Add(b3);
101 
102             // 实例化一个CustomBinaryFormatter对象,并注册为BookList类型
103             CustomBinaryFormatter f = new CustomBinaryFormatter();
104             f.Register<BookList>(1);
105 
106             // 实例化一个MemoryStream来存储序列化后的数据
107             MemoryStream ms = new MemoryStream();
108 
109             // 序列化blist并存到ms中
110             f.Serialize(ms, blist);
111 
112             // 回退到流的开始处
113             ms.Seek(00);
114 
115             // 反序列化并以此实例化一个新的BookList对象
116             BookList blist2 = (BookList)f.Deserialize(ms);
117 
118             // 测试
119             tb1.Text = blist2.BookListName;
120             for (int i = 0; i < 3; i++)
121             {
122                 tb2.Text += blist2.MyBookList[i].ID.ToString() + "\n";
123                 tb3.Text += blist2.MyBookList[i].Name + "\n";
124                 tb4.Text += blist2.MyBookList[i].GetPrivate() + "\n";
125             }
126         }
127     }
128 }