建议55:利用定制特性减少可序列化的字段

特性(attribute)可以声明式地为代码中的目标元素添加注释。运行时可以通过查询这些托管块中的元数据信息,达到改变目标元素运行时行为的目的。System.Runtime.Serialization命名空间下,有4个这样的特性:

  • OnDeserializedAttribute,当它应用于某方法时,会指定在对象反序列化后立即调用此方法。
  • OnDeserializingAttribute,当他应用于某方法是,会指定在反序列化对象时调用此方法。
  • OnSerializedAttribute,当它应用于某方法时,会指定在对象序列化后立即调用此方法。
  • OnSerializingAttribute,当他应用于某方法是,会指定在序列化对象时调用此方法。

利用这些特性,可以更加灵活地处理序列化和反序列化。例如,我们可以利用这一点,进一步减少某些可序列化的字段。

Person类由ChineseName、FirstName、LastName字段组成:

    [Serializable]
class Person
{
public string FirstName;
public string LastName;
public string ChineseName;
}

我们知道,ChineseName实际可以有FirstName和LastName推断出,所以这意味着ChineseName不需要被序列化。这时候,我们就可以利用特性,提供一个方法在序列化完成后计算ChineseName的值:

    class Program
{
static void Main()
{
Person liming = new Person() { FirstName = "Ming", LastName = "Li", ChineseName = "Li Ming" };
BinarySerializer.SerializeToFile(liming, @"c:\", "Person.txt");
Person person = BinarySerializer.DeserializeFromFile<Person>(@"c:\Person.txt");
Console.WriteLine(person.ChineseName);
}
} [Serializable]
class Person
{
public string FirstName;
public string LastName;
[NonSerialized]
public string ChineseName; [OnDeserializedAttribute]
void OnSerialized(StreamingContext context)
{
ChineseName = string.Format("{0} {1}", LastName, FirstName);
}
}

序列化工具类:

    public class BinarySerializer
{
//将类型序列化为字符串
public static string Serialize<T>(T t)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, t);
return System.Text.Encoding.UTF8.GetString(stream.ToArray());
}
} //将类型序列化为文件
public static void SerializeToFile<T>(T t, string path, string fullName)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string fullPath = Path.Combine(path, fullName);
using (FileStream stream = new FileStream(fullPath, FileMode.OpenOrCreate))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, t);
stream.Flush();
}
} //将字符串反序列化为类型
public static TResult Deserialize<TResult>(string s) where TResult : class
{
byte[] bs = System.Text.Encoding.UTF8.GetBytes(s);
using (MemoryStream stream = new MemoryStream(bs))
{
BinaryFormatter formatter = new BinaryFormatter();
return formatter.Deserialize(stream) as TResult;
}
} //将文件反序列化为类型
public static TResult DeserializeFromFile<TResult>(string path) where TResult : class
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
return formatter.Deserialize(stream) as TResult;
}
}
}

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

最新文章

  1. hdu 1159, LCS, dynamic programming, recursive backtrack vs iterative backtrack vs incremental, C++ 分类: hdoj 2015-07-10 04:14 112人阅读 评论(0) 收藏
  2. 一种集合&ldquo;相等性&rdquo;的实现
  3. 移动互联网实战--wifi定位和架构
  4. centos 7 中 tomcat 安装
  5. iOS开发项目之一 [ 项目流程]
  6. 按月将Windows日志导出至CSV文件
  7. WebGrid Enterprise免费下载
  8. python之super()函数
  9. Android学习总结——SharedPreferences
  10. Qt部件学习之-烧鹅
  11. ExceptionDemo
  12. alex python of day3
  13. &lt;iframe&gt;和&lt;frame&gt;区别
  14. 图解:window与BOM的关系
  15. Developing Vert.x Modules with Gradle
  16. (转)Spring Boot 2 (六):使用 Docker 部署 Spring Boot 开源软件云收藏
  17. ToolBar样式颜色,图标设置
  18. OpenStack设计与实现5——RESTful API和WSGI
  19. 海南小地图(echart)
  20. Chrome 调用vue.js 记录

热门文章

  1. POJ1961:Period
  2. (转)Download interrupted: Connection to https://dl-ssl.google.com refused
  3. eclipse-连接TFS错误 &lt;the server to respond with a valid http response&gt;解决方法
  4. (转)Oracle中动态SQL详解
  5. 今天去python官网下载包安装的时候的问题记录
  6. java代码=========这个代码还是有问题的。不能实现功能呀
  7. AngularJS:Service
  8. 第三章 服务治理: Spring Cloud Eureka
  9. Python基础学习七 网络编程
  10. Full Binary Tree(sdut 2882)