參考文獻:
http://code.google.com/p/protobuf-net/
http://stackoverflow.com/questions/3100207/why-i-have-to-use-protoinclude
using System;
using System.IO;
using System.Text.RegularExpressions;
using ProtoBuf;
using ProtoBuf.Meta;
namespace TestConsole
{
public class ProtobufTest : ITest
{
private static TimeSpan ts = TimeSpan.FromSeconds( 1);
/// <summary>
/// 臨時測試使用
/// </summary>
public void Run()
{
{
Console.WriteLine( " v1的序列化和反序列化測試 ");
Person p = new Student() { Sex = true, Name = " 張三 ", School = " 福州3中 " };
var arr1 = ProtobufSerialize(p);
var s1 = ProtobufDeserialize<Student>(arr1);
Console.WriteLine(s1.Sex + " ; " + s1.Name + " ; " + s1.School);
var s2 = ProtobufDeserialize<Person>(arr1);
Console.WriteLine(s2.Sex + " ; " + s2.Name);
}
Console.WriteLine();
{
Console.WriteLine( " v2的序列化和反序列化測試 ");
Animal bird = new Bird() { Sex = true, Name = " 海鷗 ", CanFly = true };
var arr2 = ProtobufSerialize(bird);
var b1 = ProtobufDeserialize<Bird>(arr2);
Console.WriteLine(b1.Sex + " ; " + b1.Name + " ; " + b1.CanFly);
var b2 = ProtobufDeserialize<Animal>(arr2);
Console.WriteLine(b2.Sex + " ; " + b2.Name);
}
}
#region 序列化和反序列化的方法
/// <summary>
/// 使用protobuf把對象序列化為Byte數組
/// </summary>
/// <typeparam name="T"> 需要反序列化的對象類型,必須聲明[ProtoContract]特征,且相應屬性必須聲明[ProtoMember(序號)]特征 </typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static Byte[] ProtobufSerialize<T>(T obj)
{
using ( var memory = new MemoryStream())
{
Serializer.Serialize(memory, obj);
return memory.ToArray();
}
}
/// <summary>
/// 使用protobuf反序列化二進制數組為對象
/// </summary>
/// <typeparam name="T"> 需要反序列化的對象類型,必須聲明[ProtoContract]特征,且相應屬性必須聲明[ProtoMember(序號)]特征 </typeparam>
/// <param name="data"></param>
public static T ProtobufDeserialize<T>(Byte[] data) where T : class
{
using ( var memory = new MemoryStream(data))
{
return Serializer.Deserialize<T>(memory);
}
}
#endregion
}
#region v1里的使用屬性的方法,每個class都必須加上ProtoContract屬性,且ProtoInclude加上子類的定義,每個屬性都要加上ProtoMember
[ProtoContract]
[ProtoInclude( 3, typeof(Student))]
public class Person
{
[ProtoMember( 1)]
public bool Sex { get; set; }
[ProtoMember( 2)]
public string Name { get; set; }
}
[ProtoContract]
public class Student : Person
{
[ProtoMember( 11)]
public string School { get; set; }
}
#endregion
#region v2里的使用RuntimeTypeModel,可以在運行時動態定義,關鍵就是在序列化必須保證會運行到Include的代碼,比如下面的Bird的靜態構造函數
public class Animal
{
public bool Sex { get; set; }
public string Name { get; set; }
}
public class Bird : Animal
{
static Bird()
{
RuntimeTypeModel a = RuntimeTypeModel.Default;
a[ typeof(Animal)].Add( 1, " Sex ").Add( 2, " Name ").AddSubType( 3, typeof(Bird)); // 這一句也可以寫在Animal的static定義里
a[ typeof(Bird)].Add( 1, " CanFly ");
}
public bool CanFly { get; set; }
}
#endregion
}
using System.IO;
using System.Text.RegularExpressions;
using ProtoBuf;
using ProtoBuf.Meta;
namespace TestConsole
{
public class ProtobufTest : ITest
{
private static TimeSpan ts = TimeSpan.FromSeconds( 1);
/// <summary>
/// 臨時測試使用
/// </summary>
public void Run()
{
{
Console.WriteLine( " v1的序列化和反序列化測試 ");
Person p = new Student() { Sex = true, Name = " 張三 ", School = " 福州3中 " };
var arr1 = ProtobufSerialize(p);
var s1 = ProtobufDeserialize<Student>(arr1);
Console.WriteLine(s1.Sex + " ; " + s1.Name + " ; " + s1.School);
var s2 = ProtobufDeserialize<Person>(arr1);
Console.WriteLine(s2.Sex + " ; " + s2.Name);
}
Console.WriteLine();
{
Console.WriteLine( " v2的序列化和反序列化測試 ");
Animal bird = new Bird() { Sex = true, Name = " 海鷗 ", CanFly = true };
var arr2 = ProtobufSerialize(bird);
var b1 = ProtobufDeserialize<Bird>(arr2);
Console.WriteLine(b1.Sex + " ; " + b1.Name + " ; " + b1.CanFly);
var b2 = ProtobufDeserialize<Animal>(arr2);
Console.WriteLine(b2.Sex + " ; " + b2.Name);
}
}
#region 序列化和反序列化的方法
/// <summary>
/// 使用protobuf把對象序列化為Byte數組
/// </summary>
/// <typeparam name="T"> 需要反序列化的對象類型,必須聲明[ProtoContract]特征,且相應屬性必須聲明[ProtoMember(序號)]特征 </typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static Byte[] ProtobufSerialize<T>(T obj)
{
using ( var memory = new MemoryStream())
{
Serializer.Serialize(memory, obj);
return memory.ToArray();
}
}
/// <summary>
/// 使用protobuf反序列化二進制數組為對象
/// </summary>
/// <typeparam name="T"> 需要反序列化的對象類型,必須聲明[ProtoContract]特征,且相應屬性必須聲明[ProtoMember(序號)]特征 </typeparam>
/// <param name="data"></param>
public static T ProtobufDeserialize<T>(Byte[] data) where T : class
{
using ( var memory = new MemoryStream(data))
{
return Serializer.Deserialize<T>(memory);
}
}
#endregion
}
#region v1里的使用屬性的方法,每個class都必須加上ProtoContract屬性,且ProtoInclude加上子類的定義,每個屬性都要加上ProtoMember
[ProtoContract]
[ProtoInclude( 3, typeof(Student))]
public class Person
{
[ProtoMember( 1)]
public bool Sex { get; set; }
[ProtoMember( 2)]
public string Name { get; set; }
}
[ProtoContract]
public class Student : Person
{
[ProtoMember( 11)]
public string School { get; set; }
}
#endregion
#region v2里的使用RuntimeTypeModel,可以在運行時動態定義,關鍵就是在序列化必須保證會運行到Include的代碼,比如下面的Bird的靜態構造函數
public class Animal
{
public bool Sex { get; set; }
public string Name { get; set; }
}
public class Bird : Animal
{
static Bird()
{
RuntimeTypeModel a = RuntimeTypeModel.Default;
a[ typeof(Animal)].Add( 1, " Sex ").Add( 2, " Name ").AddSubType( 3, typeof(Bird)); // 這一句也可以寫在Animal的static定義里
a[ typeof(Bird)].Add( 1, " CanFly ");
}
public bool CanFly { get; set; }
}
#endregion
}