zoukankan      html  css  js  c++  java
  • clr via c# 运行时序列化

    1,快速了解序列化----windows IO 系统,FileStream,BinaryFormatter,SoapFormatter--不支持泛型.

    public class SerializeRef
        {
            public static void CallQuick()
            {
                dynamic objectgrap = new List<string>() { "jeff", "kristin", "aldan", "grant" }.ToArray<string>();
    
                using (var st = new FileStream("mxb.xml", FileMode.Create))
                {
                    SoapFormatter formatter = new SoapFormatter();
                    formatter.Serialize(st, objectgrap);
                    st.Position = 0;
                    objectgrap = null;
                    var objectgrap1 = ((string[])formatter.Deserialize(st)).ToList<string>();
                    objectgrap1.ForEach(x => Display(0, x));
                }
    
    
            }
            private static void Display(int indent, string Format, params object[] obj)
            {
                Console.Write(new string(' ', indent * 2));
                Console.WriteLine(Format, obj);
            }
        }

      

           利用BinaryFormatter.Serialize配合流进行对象图的写入.

           利用BinaryFormatter.DeSerialize进行对象图的还原

           流对象st.Postion如果没设置会报错.

    2, 利用序列化创建对象的深拷贝.

     private static object DeepClone(object ori)
            {
                using(MemoryStream ms=new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Context = new StreamingContext(StreamingContextStates.Clone);
                    bf.Serialize(ms, ori);
                    ms.Position = 0;
                    return bf.Deserialize(ms);
                }
            }

       //注意Context中的一个用法,表明这是一个流的一个克隆过程,告诉其他线程该如何处理原对象.

    3,利用序列化保存和恢复程序的状态.

     public static void CallSerilalMultiple()
            {
                List<Customer> s_customers = new List<Customer>() { new Customer("abc"),};
                List<order> s_orders = new List<order>() { new order("abc"), };
                using(var fs=new FileStream("mxb.dat", FileMode.OpenOrCreate))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, s_customers);
                    bf.Serialize(fs,s_orders);
                    s_customers = null;
                    s_orders = null;
                    GC.Collect();
                }
                using (var fs = new FileStream("mxb.dat", FileMode.OpenOrCreate))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    s_customers = (List<Customer>)(bf.Deserialize(fs));
                    s_orders = (List<order>)(bf.Deserialize(fs));
                }
                s_customers.ForEach(x => Display(0, x.name));
                s_orders.ForEach(x => Display(0, x.name));
            }
    //result

    Customerabc ;成功的反序列化原来的对象.
    orderabc;成功反序列化原来的对象.

    4,让对象可序列化  定制特性SerializableAttribute

    只能用于 class,struct,枚举类型和委托类型(后两者总是可序列化).

    Serializable特性不被派生类继承,

    5,控制序列化

    序列化应用于类型时,所有的实列字段都会被序列化.(类的对象),使用NonSerialized,这样,某个字段就不会被序列化.当反序列化的时候,该字段自动清0.

    类可设定四个方法进行控制:

    •          private void OnSerializing(StreamContext context)---序列化之前[OnSerializing]
    •          private  void  OnSerialized(streamContext context)---序列化完成后[OnSerialized]
    •          private void  OnDeSerialized(streamContext context)---反序列化之前[OnDeSerializing]
    •          private void  OnDeSerialized(stream Context context)---反序列化之后[OnDeSerialized]

    序列化一组对象前,先调用标记OnSerializing特性的所有方法.接着序列化所有字段,接着调用标记OnSerialized特性的所有方法.

    反序列化前,先调用OnDeserializing特性的所有方法,然后反序列化所有的对象字段,然后调用标记了OnDeserialized方法.

    运行OnDeserialized方法前,会进行由内而外的反序执行(先执行对象指向对象的方法,最后才是对象的方法).

    6,格式化器序列化类型实列的过程

              1,使用FormatterServices.GetSerializableMembers,获取(public,private)的可序列化字段

    一个MemberInfo[] 数组

              2,调用FormatterServices.GetObjectData(obj,memberinfos)来获取各个字段的data,一个object[]数组,和上面对应.

     public static void CallHowSerialize()
            {
                Customer ct = new Customer("nameadef");
                //1,通过该函数获得类的public和private的字段.
                 MemberInfo[] mis= FormatterServices.GetSerializableMembers(typeof(Customer));//可以获取隐藏的属性字段.可获取私有字段.
                
                Array.ForEach<MemberInfo>(mis, x => Display(0,"{0}", x.Name));
                //获取字段的值...
                Display(0, "");
                object[] objs = FormatterServices.GetObjectData(ct, mis);
                Array.ForEach<object>(objs, x => Display(0, "{0}", x.ToString()));
            }

            3,将程序集标识和类型完整名称写入流中

            4,遍历两个数组的元素,将名称和值写入流中

    7,反序列化实列的流程

                 1,格式化器从流中读取程序集标识和完整的类名称,如果程序集未加载,就试图加载程序集.如果已经加载,就调用函数

                   FormatterServices.GetTypeFromAssembly(assembly,string name)获得需要反序列化的对象的类型.

                 2,格式化器调用FormatterServices的静态方法

                    public static object GetUninitializedObject(Type type)为对象分配内存,但是不为对象调用构造器.然而,所有的字节都

                  被初始化为null,或0;

                 3,格式化器现在构造,并初始化一个MemberInfo数组,获得MemberInfo[]数组,表示需要反序列化的字段

                 4,格式化器根据流中包含的字段值反序列化为一个object[]数组.

                 5,将新分配的对象,MemberInfo数组以及Object数组的引用传递给FormatterServices的静态方法

    public static object PopulateObjectMembers(
    object obj,
    MemberInfo[] mis,
    object[] datas);

    举列:----

     public static void CallHowSerialize()
            {
                Customer ct = new Customer("nameadef");
                //1,通过该函数获得类的public和private的字段.
                 MemberInfo[] mis= FormatterServices.GetSerializableMembers(typeof(Customer));//可以获取隐藏的属性字段.可获取私有字段.
                //无法获取隐藏的属性字段.
                Display(0, "Filds to be Serialized:");
                Array.ForEach<MemberInfo>(mis, x => Display(1,"{0}", x.Name));
                //获取字段的值...
                Display(0, "Filds Data to be Serialized:");
                object[] objs = FormatterServices.GetObjectData(ct, mis);
                Array.ForEach<object>(objs, x => Display(1, "{0}", x.ToString()));
                //反序列化对象
                Customer dct = null;
                //获得需要反序列化对象的类型:
                Type t = FormatterServices.GetTypeFromAssembly(Assembly.GetEntryAssembly(), typeof(Customer).FullName);
                //创建一个初始化但未调用构造器的类对象
                dct = (Customer)FormatterServices.GetUninitializedObject(t);
                Display(0, "
     Before Deserialized FieldsData");
                Display(1,"name is {0}",dct.name??"None");
                dct =(Customer) FormatterServices.PopulateObjectMembers(dct, mis, objs);
                Display(0, "
     After Deserialized FieldsData");
                Display(0, "name is {0}", dct.name);
            }

    Filds to be Serialized:
       name
       t
       <Props>k__BackingField
    Filds Data to be Serialized:
       Customernameadef
       0
       0

    Before Deserialized FieldsData
       name is None

    After Deserialized FieldsData
    name is Customernameadef

    1,反序列化过程不调用构造器

    2,通过上面函数可以设定私有字段.

    8,控制序列化和反序列化的数据----ISerializable接口:

    void GetObjectData(SerializationInfo info,StreamingContext context)----一旦某个类实现了它,其派生类也必须实现.(所以,实现了该接口的类最好是密封的sealed).

        如果有该接口,那么在序列化的时候,开始使用info.add添加(key,可序列化对象).然后序列化SerializationInfo对象,并序列化其中引用的所有序列化对象.

        在反序列化的时候,就反序列化SerializationInfo对象,然后调用反序列化构造器,将这个参数和StreamingContext对象传递给反序列化构造器.

        当使用GetValue对象获得的对象和你视图获取的对象不符合,则将调用对象的IFormatterConverter对象,将 GetValue取得的对象进行转换

     s2 = (SerializeTwo)info.GetValue("s2", typeof(object));//后一个是获得对象要转换的类型.

        1,首先创建一个类 SerializeOne

                   首先该类有3个字段.

                   该类有两个构造器

                   该类有一个反序列化构造器

                   该类的序列化函数将字段加入info

                  该类的反序列化构造器将信息读出并显示

                 

    internal  class SerializedOne:ISerializable,IDeserializationCallback
        {
            private string m_name;
            private int m_int;
            private List<string> list=new List<string>();
    
    
            public SerializedOne():this("initial",default(int),null)
            {
    
            }
            public SerializedOne(string name,int int1,params string[] strs)
            {
                m_name = name;
                m_int = int1;
                if(strs!=null)list.AddRange(strs);
    
            }
    
            public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("List", list);
                info.AddValue("m_name", m_name);
                info.AddValue("m_int", m_int);
    
    
            }
    
            public void OnDeserialization(object sender)
            {
                Console.WriteLine("DeSerialized!");
            }
            protected SerializedOne(SerializationInfo  info,StreamingContext context)//反序列化构造器,进行反序列化一个新的未构造对象后,进行运行;
            {
                list =(List<string>) info.GetValue("List",typeof(object));
                m_int = (int)info.GetValue("m_int", typeof(int));
                m_name = (string)info.GetValue("m_name", typeof(string));
    
                Console.WriteLine("DeSerialized Constructor");
                foreach(var enter in info)
                {
                    Console.WriteLine(enter.Name+" : "+enter.Value);
                }
            }
            public override string ToString()
            {
                string str=string.Format("
    m_name={0}:m_int={1}", m_name, m_int);
                int index = 0;
                list.ForEach(x => str = str + string.Format("
    Item {0} = {1} ", index++, x));
                return str;
            }
            public virtual void Display() { Console.WriteLine(this.ToString()); }
        }

            2,创建一个类2继承自类1..(类2同时继承了类1的所有字段)

                 该类重写了类1的几个方法

    internal class SerializeTwo:SerializedOne,ISerializable
        {
            public  string name;
            public SerializeTwo(string name):base(name,100,"abc","efg") { this.name = name; }
            private SerializeTwo(SerializationInfo info, StreamingContext context):base(info,context)//反序列化构造器,进行反序列化一个新的未构造对象后,进行运行;
            {
                name = (string)info.GetValue("name", typeof(string));
            }
    
            public override  void  GetObjectData(SerializationInfo info, StreamingContext context)
            {
                base.GetObjectData(info, context);
                info.AddValue("name", this.name);
    
            }
            public override string ToString()
            {
                return base.ToString() + string.Format("
    SerializedTwo's name ={0}", this.name);
            }
            public override void Display()
            {
    
                Console.WriteLine(ToString());
            }
        }

            

              3,进行测试:

     public static void CallISerializedTwo()
            {
                Console.WriteLine("Show Fileds of SerializeTwo [[[[[:--------------");
                    MemberInfo[] mis = FormatterServices.GetSerializableMembers(typeof(SerializeTwo));//可以获取隐藏的属性字段.可获取私有字段.
                Array.ForEach<MemberInfo>(mis, x => Display(1, "{0}", x.Name));
    
                Console.WriteLine("Show Fileds of SerializeTwo ]]]]:--------------");
                SerializeTwo so = new SerializeTwo("mxb");
                so.Display();
                using (var fs = new FileStream("mxb.dat", FileMode.OpenOrCreate))
                {
                    SerializedGJ.Serialize(fs, new BinaryFormatter(), so);
                }
                so = null;
    
                using (var fs = new FileStream("mxb.dat", FileMode.OpenOrCreate))
                {
                    so = (SerializeTwo)SerializedGJ.DeSerialize(fs, new BinaryFormatter());
                    so.Display();
                }
            }

    Show Fileds of SerializeTwo [[[[[:--------------
       name
       SerializedOne+m_name
       SerializedOne+m_int
       SerializedOne+list
    Show Fileds of SerializeTwo ]]]]:--------------

    m_name=mxb:m_int=100
    Item 0 = abc
    Item 1 = efg
    SerializedTwo's name =mxb
    DeSerialized Constructor
    List : System.Collections.Generic.List`1[System.String]
    m_name : mxb
    m_int : 100
    name : mxb
    DeSerialized!

    m_name=mxb:m_int=100
    Item 0 = abc
    Item 1 = efg
    SerializedTwo's name =mxb

    结果:   1,表明派生类继承了基类的字段

              2,当未序列化的时候,各个字段的值

              3,将so引用清0,然后进行反序列化

              4,显示了info类的Key,value内容,

              5,显示类2的所有字段的值.

    9,利用如何序列化一个没有被标记为序列化的类

    [Serializable]
        internal sealed class NoSerializableToSerialized:ISerializable //我写的一个可以包装未设置序列化类的类.
        {
            private object m_obj;
            private const BindingFlags c_bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField;
    
            public object Obj { get { return m_obj; } }
            public NoSerializableToSerialized(object obj) { m_obj = obj; }
    
            private NoSerializableToSerialized(SerializationInfo info, StreamingContext context)
            {
                Type t = (Type)info.GetValue("TypeOfObject", typeof(Type));//反序列化m_obj的对象类型.
                m_obj = Activator.CreateInstance(t);//创建类型实列.
                FieldInfo[] mis = null;
    
                if (m_obj.GetType().IsDefined(typeof(SerializableAttribute)))//如果是序列化类调用....
                {
                    mis = (FieldInfo[])FormatterServices.GetSerializableMembers(m_obj.GetType());
    
                }
                else//非序列化类调用....
                {
                    mis = m_obj.GetType().GetTypeInfo().GetFields(c_bf);
    
                }
    
    
    
    
                for (int i = 0; i < mis.Length; i++)
                {
                    var mi = mis[i];
    
                    if (!mi.FieldType.GetTypeInfo().IsDefined(typeof(SerializableAttribute)))//非序列化类,迭代解析.
                    {
    
                        var objss = (NoSerializableToSerialized)info.GetValue(mi.Name + i, typeof(NoSerializableToSerialized));
                        mi.SetValue(m_obj, objss.Obj);
                    }
                    else//否则直接获得对象.
                    {
                        mi.SetValue(m_obj, info.GetValue(mi.Name + i, mi.FieldType));
                    }
    
                }
    
    
    
            }
            //自定义序列化函数
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
    
                info.AddValue("TypeOfObject", m_obj.GetType(), typeof(Type));//将对象类型序列化
                FieldInfo[] mis = null;
                object[] objs = null;
                if (m_obj.GetType().IsDefined(typeof(SerializableAttribute)))//如果是序列化类型,调用GetSerializableMembers
                {
                    mis =(FieldInfo[])FormatterServices.GetSerializableMembers(m_obj.GetType());
                    objs = FormatterServices.GetObjectData(m_obj, mis);
                    Console.WriteLine("
     defined serial");
                }
                else//如果是非序列化,调用GetFields.
                {
                    mis = m_obj.GetType().GetTypeInfo().GetFields(c_bf);
                    objs = FormatterServices.GetObjectData(m_obj, mis);
                }
    
                for (int i = 0; i < mis.Length; i++)
                {
                    var mi = mis[i];
                    var obj = objs[i];
                    //如果Field是非序列化对象,则进行包装,再序列化.否则直接加入Info
                    if (!mi.FieldType.GetTypeInfo().IsDefined(typeof(SerializableAttribute)))
                    {
                        info.AddValue(mi.Name + i, new NoSerializableToSerialized(obj));
                    }
                    else
                    {
                        info.AddValue(mi.Name + i, obj);
                    }
    
                }
    
    
            }
    
        }

    10,单实列对象序列化


    public sealed class Singleton : ISerializable
        {
            private static readonly Singleton s_theOneObject = new Singleton();
            public string Name = "Jeff";
            public DateTime Date=DateTime.Now;
            private Singleton() { }
    
            public static Singleton GetSingleton() { return s_theOneObject; }
    
            void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.SetType(typeof(SingletionSerializationHelper));
            }
            private Singleton(SerializationInfo info, StreamingContext context)//该函数未运行.
            {
                Console.WriteLine("Deserialization Singletion");
            }
            [Serializable]
            private sealed class SingletionSerializationHelper : IObjectReference
            {
                public object GetRealObject(StreamingContext context)
                {
                    return Singleton.GetSingleton();
                }
            }
        }

      1,使用SetType表示在序列化的时候将序列化一个SingletionSerializationHelper对象,----将该对象的程序集和类型信息写入序列化中

      2,在反序列化的时候,格式化器知道这是一个由类型转换来的对象.所以它首先反序列化成一个SingletionSerializationHelper对象.

      注意:该对象必须实现接口IObjectReference,然后调用该对象的GetRealObject对象---让它返回一个所需要的对象.(这个方法主要用于对单实列类进行保存.


    11,序列化代理:(利用代理可以重写和覆盖,将类型反馈为一个不同的版本)

    序列化代理必须事件ISerializationSurrogate接口

    该接口实现了2个函数:

    GetObjectData(Object, SerializationInfo, StreamingContext)
    //用序列化对象所需的数据填充所提供的 SerializationInfo。
    SetObjectData(Object, SerializationInfo, StreamingContext, ISurrogateSelector)
    反序列化时,利用其将SerializationInfo中
    •           当某个类型 和 序列化代理关联的时候,那么,序列化这个对象,就调用了GetObjectData方法,(ISerializable)中的方法.并且

    第一个参数为,该类型的实列,第二个参数为格式化器提供的Info.

              当反序列化的时候,首先使用FormatterServices.GetUninitializedObject()建立一个关联类型的未初始化的实列.该实列的所有的Field是NUll,或者0;

              然后这个参数作为第一个参数传给SetObjectData,这个参数可用,可不用.

    •     首先创建一个需要代理的类(测试用,非实现Serializable)
    •  public class TestForSurrogate//一个测试类,当序列化的时候,不管序列化时间,反序列化的时候,更新其时间
          {
              public DateTime dt = DateTime.Now;
              public String Name;
              public TestForSurrogate(string name)
              {
                  Name = name;
              }
          }

                 

    public sealed class MySurrogateForSurrogateTest : ISerializationSurrogate
        {
            public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
            {
                TestForSurrogate Myboj = (TestForSurrogate)obj;
                Myboj.dt = DateTime.Now;
                Console.WriteLine(Myboj.Name+Myboj.dt.ToString());
                info.AddValue("Name", Myboj.Name);
                info.AddValue("time", Myboj.dt);
            }
    
            public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
            {
                TestForSurrogate Myboj = (TestForSurrogate)obj;
                Myboj.dt = (DateTime)info.GetValue("time",typeof(object));
                Myboj.Name = (string)info.GetValue("Name", typeof(object));
                Console.WriteLine(Myboj.Name + Myboj.dt.ToString());
                return Myboj;
            }
        }

    然后创建一个surrogateSelector对象,并且进行绑定

     SurrogateSelector selector = new SurrogateSelector();
                    selector.AddSurrogate(typeof(TestForSurrogate), formatter.Context, new MySurrogateForSurrogateTest());

    然后将其赋值给,Formmater的SurrogateSelecotor属性

     formatter.SurrogateSelector = selector;
    • 然后就能工作了,当序列化       一个TestForSurrogate对象,就会调用MySurrogateForSurrogateTest.GetObjectData
    •              当反序列化时候,就会调用MySurrogateForSurrogateTest.SetObjectData

    注意,Selector实现了接口ISurrogateSelector接口:

    ChainSelector 将Selector链接起来

    GetNextSelector 获得下一个Selector

    GetSurrgate,在Selector链中查找.

                   相当于KeyValue<type,Surrogate)----组成了一个 Selector,

                   Selector.Chain(Selector1)将Selector1加入到Selector链中.


       12,反序列化的时候重写程序集/类型-----------SerializationBinder对象的使用.

            1,自己实现一个SerializationBinder的派生类.

     public class MySerializationBinder : SerializationBinder
        {
            public override Type BindToType(string assemblyName, string typeName)
            {
                Console.WriteLine("BInderToType...");
                Console.WriteLine("
    " + assemblyName);
                Console.WriteLine("
    " + typeName);
                //return Type.GetType(typeName +","+ assemblyName);//加,号,因为否则生成的typename是不完整的.
                return typeof(TestForSurrogate1);
            }
    
    
        }

        2,其赋值给Formmater.Binder

    formatter.Binder = new MySerializationBinder();

       3,实现绑定类型类,将---类TestForSurrogate返回给类TestForSurrogate1


     public sealed class TestForSurrogate1:ISerializable//一个测试类,当序列化的时候,不管序列化时间,反序列化的时候,更新其时间
        {
            public DateTime dt = DateTime.Now;
            public String Name;
            public TestForSurrogate1(string name)
            {
                Name = name;
            }
            private TestForSurrogate1(SerializationInfo info, StreamingContext context)
            {
                Console.WriteLine("test1 Deserialized..");
                try
                {
                    info.GetValue("Test1", typeof(TestForSurrogate1));
                }
                catch(Exception)
                {
                    Console.WriteLine("it's From Surrogate v1.0");
                    this.Name = (string)info.GetValue("Name", typeof(object));
                    this.dt = DateTime.Now;
                }
    
            }
    
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("Test1", this);
            }
        }

       4,测试如下代码

    public static void Call1()
            {
                using (var st = new FileStream("mxb.xml", FileMode.Create))
                {
                    SoapFormatter formatter = new SoapFormatter();
                    SurrogateSelector selector = new SurrogateSelector();
                    selector.AddSurrogate(typeof(TestForSurrogate), formatter.Context, new MySurrogateForSurrogateTest());
                    formatter.SurrogateSelector = selector;
                    formatter.Binder = new MySerializationBinder();
                    formatter.Serialize(st, new TestForSurrogate("mxb"));
                    //必须,表明要格式化的位置?
                    st.Position = 0;
                    var objectgrap1 = formatter.Deserialize(st);
                    Console.WriteLine(objectgrap1.GetType().ToString());
                    Console.WriteLine(((TestForSurrogate1)objectgrap1).Name);
    
                }
            }
        }

       其结果如下:

    mxb2020/2/19 21:32:55
    BInderToType...
    
    ClrFromCSharp_2_2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=11fccde6e91ad1e9
    
    ClrFromCSharp_2_2.LearnSerialize.TestForSurrogate
    test1 Deserialized..
    it's From Surrogate v1.0
    ClrFromCSharp_2_2.LearnSerialize.TestForSurrogate1
    mxb
    
    

    xml文件内容如下

    <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
    <a1:Singleton_x002B_SingletionSerializationHelper id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/ClrFromCSharp_2_2.LearnSerialize/ClrFromCSharp_2_2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D11fccde6e91ad1e9">
    <Name id="ref-3">Jeff</Name>
    </a1:Singleton_x002B_SingletionSerializationHelper>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

    表明对象序列化的绑定器和绑定的类别.  ------------就是创建了一个单实列的SingletionSerializationHelper.

    当反序列化的时候,格式化器通过selector知道这个Selector绑定的类别

    然后创建该类别非初始化实列

    然后传递给SetObjectData的第一个参数.执行这个函数.

    --------------

    当由Binder之后,对象在反序列化的时候,首先

    •          执行Binder的BinderToType函数,然后返回了一个Type.
    •          然后,如果该类型有ISerialize接口,调用反序列化构造器.
    •          否则,调用默认反序列化过程,见上面.

    上面的列子很有意思

    由于Selector和Surrogate的缘故,首先当序列化一个TestForSurrogate对象的时候,会先调用代理的序列化函数.

    但是,由于binder的作用,再返回的时候,因为,创建了一个TestForSurrogate1对象,会调用TestForSurrogate1,的反序列化构造器.

  • 相关阅读:
    磁盘与文件系统管理
    zookeeper安装部署
    linux打包与压缩
    MongoDB聚合查询
    scrapy中选择器用法
    scrapy基本用法
    python操作mongoDB
    超详细windows安装mongo数据库、注册为服务并添加环境变量
    python beautifulsoup基本用法-文档搜索
    python beautifulsoup基本用法-文档结构
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12336879.html
Copyright © 2011-2022 走看看