zoukankan      html  css  js  c++  java
  • 《Effective C#》读书笔记——条目27:让类型支持序列化<使用C#表达设计>

      持久化(persistence)是类型的一个重要特性。只要我们的类型不是UI控件、窗体或者表单,都应该尽可能的为类型添加序列化支持。.NET的序列化是把类中所有成员变量保存到输出流中,同时.NET的序列化还支持任意的对象图(object graph):即使你的对象上有一个循环引用,serialize 和deserialize 方法都只会为你的实际对象读取和储存一次。

    1. .NET的序列化支持

      在.NET中支持序列化是一件非常简单的任务,在绝大多数的情况下,只需要添加一个Serializable特性就可以了。但是这里有一个前提:

    使用Serializable特性对类进行序列化支持,要求该类的所有成员都是可序列化的。

    例如,下面的例子,由于int和string类型都是支持.NET序列化,所有我们只需要简单的添加Serializable特性即可。

    1     [Serializable]
    2     public class MyType
    3     {
    4         private string lable;
    5         private int value;
    6     }

    反之,如果在一个类中如果有成员不支持序列化,而又使用Serializable,例如下面的代码中,由于OhterClass类没有序列化支持,在序列化MyType时,会得到一个运行时错误。

    1 [Serializable]
    2 public class MyType
    3 {
    4     private string lable;
    5     private int value;
    6     private OtherClass other;
    7 }

    2.正确的初始化使用NonSerialized特性的成员

      添加Serializable特性是支持对象序列化的最简单方式,但最简单的方式却不一定总是这却的方式。假如:我们并不想序列化对象的所有成员:比如某些成员可能只存在于与长期操作的缓存中、或者占用着一些运行时资源,而这些资源只存在于与内存中时我们该如何解决这一问题呢?同样,我们可以通过添加NonSerialized特性到任何你不想让它序列化的数据成员上:

    1     [Serializable]
    2     public class MyClass
    3     {
    4         public int Id{get;set;}
    5         [NonSerialized]
    6         public int CachedValue{get;set;}
    7         public string Name{get;set;}
    8     }

      当我们使用NonSerialized特性时,我们同时也需要完成一些额外的工作:因为在反序列化的过程中.NET序列化API不会初始化使用NonSerialized特性的成员,同时由于类型的构造函数不会被调用,所有成员的初始化器也就不会被执行。当使用Serializable特性时,那些使用NonSerialized特性的成员只会得到系统设定的默认值:0或null(值类型或引用类型);如果系统默认的初始化行为并不是我们想要的效果,那么着时候我们可以通过实现IDeserializationCallback接口来对这些成员进行初始化。在整个对象图被反序列化之后,.NET会自动调用该接口唯一的OnDeserialization()方法。

  • 相关阅读:
    纸牌排序
    将年份转换成天干地支
    猜算式
    字符串的简单处理
    九宫格填数字
    扫雷
    嗨喽
    Input.GetAxis与Input.GetAxisRaw区别
    C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
    开发游戏所需知识(知乎转载)
  • 原文地址:https://www.cnblogs.com/IPrograming/p/EffectiveCSharp_27.html
Copyright © 2011-2022 走看看