编写高质量代码改善C#程序的157个建议——建议55:利用定制特性减少可序列化的字段
2015-08-17 00:46
661 查看
建议55:利用定制特性减少可序列化的字段
特性(attribute)可以声明式地为代码中的目标元素添加注释。运行时可以通过查询这些托管块中的元数据信息,达到改变目标元素运行时行为的目的。System.Runtime.Serialization命名空间下,有4个这样的特性:
OnDeserializedAttribute,当它应用于某方法时,会指定在对象反序列化后立即调用此方法。
OnDeserializingAttribute,当他应用于某方法是,会指定在反序列化对象时调用此方法。
OnSerializedAttribute,当它应用于某方法时,会指定在对象序列化后立即调用此方法。
OnSerializingAttribute,当他应用于某方法是,会指定在序列化对象时调用此方法。
利用这些特性,可以更加灵活地处理序列化和反序列化。例如,我们可以利用这一点,进一步减少某些可序列化的字段。
Person类由ChineseName、FirstName、LastName字段组成:
我们知道,ChineseName实际可以有FirstName和LastName推断出,所以这意味着ChineseName不需要被序列化。这时候,我们就可以利用特性,提供一个方法在序列化完成后计算ChineseName的值:
序列化工具类:
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
特性(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个建议》陆敏技
相关文章推荐
- 编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化
- 编写高质量代码改善C#程序的157个建议——建议53:必要时应将不再使用的对象引用赋值为null
- C#的try…catch语句
- C#编程:Predicate<T> 委托
- 【C#】程序集中资源文件的使用
- C#基础--之数据类型
- c# 自定义控件
- C#中图片.BYTE[]和base64string的转换
- C# 抽象类与抽象方法的作用与实例
- C#中的数学类,Math,浮点数(中)
- 写出高性价比代码之C#建议第52-及时释放资源
- 说说C#的数学类,Math,浮点数(上)
- C#实现远程桌面自动登录
- 编写高质量代码改善C#程序的157个建议——建议52:及时释放资源
- 编写高质量代码改善C#程序的157个建议——建议51:具有可释放字段的类型或拥有本机资源的类型应该是可释放的
- 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源
- 编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法
- C#基础系列——异步编程初探:async和await
- 编写高质量代码改善C#程序的157个建议——建议48:Dispose方法应允许被多次调用
- 编写高质量代码改善C#程序的157个建议——建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理