• 《CLR via C#》读书笔记 之 运行时序列化 明


    第二十四章 运行时序列化

    2013-04-10

    24.1 序列化/反序列化快速入门
    24.2 使类型可序列化
    24.3 控制序列化和反序列化

    序列化(serialization)是将一个对象或者对象图转换成字节流的过程。反序列化(deserialization)是将一个字节流转换会对象的过程。在对象和字节流之间转换时非常有用的机制。下面是一些例子:

    应用程序的状态(对象图)可以保存到磁盘文件或数据库,并在应用程序下次运行时恢复。如asp.net就是利用它来保持和恢复会话状态的。

    一个对象可以轻松复制到系统的剪贴板,在粘贴会同一个或另一个应用程序。windows窗体和wpf就是利用这个功能。

    一组对象可以可以轻松的通过网络发给另一台机器上运行的进程。Microsoft .net framework的Remoting架构会对按值封送的对象进行序列化和反序列化。这个技术还可以跨越AppDomain边界发送对象。

    除了上述应用,一旦将对象序列化为内存中的一个字节流,可以使用一些更有用的方式来方便的处理数据,比如加密和压缩数据等。

    24.1 序列化/反序列化快速入门


    返回

    View Code
     1 using System.IO;
     2 using System.Reflection;
     3 using System.Runtime.Serialization;
     4 using System.Runtime.Serialization.Formatters.Binary;
     5 
     6 internal static class QuickStart {
     7    public static void Go() {
     8       // Create a graph of objects to serialize them to the stream 
     9       var objectGraph = new List<String> { "Jeff", "Kristin", "Aidan", "Grant" };
    10       Stream stream = SerializeToMemory(objectGraph);
    11 
    12       // Reset everything for this demo
    13       stream.Position = 0;
    14       objectGraph = null;
    15 
    16       // Deserialize the objects and prove it worked
    17       objectGraph = (List<String>)DeserializeFromMemory(stream);
    18       foreach (var s in objectGraph) Console.WriteLine(s);
    19    }
    20 
    21    private static MemoryStream SerializeToMemory(Object objectGraph) {
    22       // Construct a stream that is to hold the serialized objects
    23       MemoryStream stream = new MemoryStream();
    24 
    25       // Construct a serialization formatter that does all the hard work
    26       BinaryFormatter formatter = new BinaryFormatter();
    27 
    28       // Tell the formatter to serialize the objects into the stream
    29       formatter.Serialize(stream, objectGraph);
    30 
    31       // Return the stream of serialized objects back to the caller
    32       return stream;
    33    }
    34 
    35    private static Object DeserializeFromMemory(Stream stream) {
    36       // Construct a serialization formatter that does all the hard work
    37       BinaryFormatter formatter = new BinaryFormatter();
    38 
    39       // Tell the formatter to deserialize the objects from the stream
    40       return formatter.Deserialize(stream);
    41    }
    42 }

    FCL提供了两个格式化器:Binaryformatter和SoapFormatter。要序列化一个对象图,只需调用格式化器的Serialize方法 。方法原型如下:

    View Code
    1 public void Serialize(Stream serializationStream, object graph);

    格式化器调用Serialize方法是,为了确保对象图中所有对象都被序列化到流中,格式器会参考每个类型的元数据。序列化时,利用反射来查看每个对象类型中有哪些实例字段,这些实例字段中,又有哪些引用了其他对象,然后对他们进行序列化。

    序列化是应注意:

    1)使用相同的格式化器进行序列化和反序列化。

    2)序列化一个对象时,类型的全名和类型定义的程序集名称会被写入流。在反序列化是,会用这些信息,会用System.Reflection.Assembly.Load方法加载程序集,再在程序集中找到匹配的类型,找到后创建类型的实例,并用流中的值对其字段进行初始化。

    24.2 使类型可序列化


    返回

    FCL得内置类型或者说基元类型已经标识的特性[Serializable],使得他们可序列化。

    使类型可序列化语法很简单,只需在类上标上特性[Serializable],它是在System命名空间中定义的。

    SerializableAttribute这个特性只能应用于引用类型、值类型。除此之外,这个特性是不会被派生类继承的;反之,则不亦然因此System.Object标识了这个特性。

    24.3 控制序列化和反序列化


    返回

    类标识上特性[Serializable]后,所有实例字段(public,private,protected)都会被序列化,有时我们不希望某些字段被实例化,如下情况:

    • 字段之在当前进程内有效,如句柄。
    • 字段含有很容易计算的信息

    标识字段不需序列化也很简单,只需在字段前标上特性[NonSerializable]即可。注意:该特性不会被派生类继承。

    但当一个字段没有序列化,会在反序列化化是出现问题,如某些方法用到这个字段,需要当前值,FCL提供了以下方法:

    View Code
     1       [OnSerializing]
     2       private void OnSerializing(StreamingContext context) 
     3       {//在序列化前,修改任何需要修改的状态 }
     4       [OnSerialized]
     5       private void OnSerialized(StreamingContext context) 
     6      {//在序列化后,恢复任何需要修改的状态 }
     7 
     8       [OnDeserializing]
     9       private void OnDeserializing(StreamingContext context) 
    10       {//在反序列化前,修改任何需要修改的状态 }
    11       [OnDeserialized]
    12       private void OnDeserialized(StreamingContext context) 
    13       {// 在反序列化后,恢复任何需要修改的状态}
  • 相关阅读:
    HTTP状态码
    NSData NSDate NSString NSArray NSDictionary 相互转换
    NSDictionary to jsonString || 对象转json格式
    git 上传本地文件到github
    NSAssert用法
    深入理解GCD(一)
    ug-Assertion failure in [MyClass layoutSublayersOfLayer:]
    构建之法阅读笔记01
    学习进度
    四则运算程序
  • 原文地址:https://www.cnblogs.com/Ming8006/p/3012778.html
Copyright © 2020-2023  润新知