参考文献:
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
}