关于Protobuf类型继承问题


参考文献:

 

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( 3typeof(Student))]
     public  class Person
    {
        [ProtoMember( 1)]
         public  bool Sex {  getset; }

        [ProtoMember( 2)]
         public  string Name {  getset; }
    }

    [ProtoContract]
     public  class Student : Person
    {
        [ProtoMember( 11)]
         public  string School {  getset; }
    }
     #endregion


     #region v2里的使用RuntimeTypeModel,可以在运行时动态定义,关键就是在序列化必须保证会运行到Include的代码,比如下面的Bird的静态构造函数
     public  class Animal
    {
         public  bool Sex {  getset; }
         public  string Name {  getset; }
    }

     public  class Bird : Animal
    {
         static Bird()
        {
            RuntimeTypeModel a = RuntimeTypeModel.Default;
            a[ typeof(Animal)].Add( 1" Sex ").Add( 2" Name ").AddSubType( 3typeof(Bird)); //  这一句也可以写在Animal的static定义里
            a[ typeof(Bird)].Add( 1" CanFly ");
        }
         public  bool CanFly {  getset; }
    }
     #endregion

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM