關於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