建议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个建议》陆敏技

编写高质量代码改善C#程序的157个建议——建议55:利用定制特性减少可序列化的字段的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议[1-3]

    原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...

  2. 读书--编写高质量代码 改善C#程序的157个建议

    最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...

  3. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试

    建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...

  4. 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本

    建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...

  5. 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码

    建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...

  6. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

  7. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  8. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...

  9. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  10. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

随机推荐

  1. What’s that ALUA exactly?

    What’s that ALUA exactly? 29 September, 20098 Comments Of course by now we have all read the excelle ...

  2. Does Windows have a limit of 2000 threads per process?

    http://blogs.msdn.com/b/oldnewthing/archive/2005/07/29/444912.aspx Often I see people asking why the ...

  3. 【转】Jmeter + DadBoby 安装使用

    一直接触LR比较多,这阵子突然想了解一下开源的性能测试工具,无意中接触到了Jmeter+Badboy,这两款工具对于想进行性能测试,但又对LR高额的商业费用望而止步的小公司可谓是再适合不过了. 自已小 ...

  4. java分割函数split的用法(二)

    package com.b; public class Sysetm { public static void main(String[] args) { String a=new String(&q ...

  5. oracle 11g r2 rac +openfiler 2.99 +centos 6.5+vbox

    继上篇openfiler 2.99安装之后,这一篇讲介绍openfiler的存储配置和oracle 端的服务配置 参考文档:https://www.oracle.com/technetwork/cn/ ...

  6. postgresql 9.5 pgpool 主从复制 以及错误解决

    PostgreSQL+pgpool-II复制方案 这里不做功能的描述,只写搭建的过程和遇到的一些问题 1 系统 [root@mysqlhq ~]# cat /etc/redhat-release Ky ...

  7. cin cout getline string

    1.C++ code, When we want to read a number whatever the type is int or double , just use cin >> ...

  8. 微信小程序中在页面中实现下拉刷新显示提醒语后在消失

    最近在做小程序的时候遇见一个问题,就是页面要下拉刷新给客户一个提醒语,查看了小程序的官方文档 这里有个注意点:如果你是一页进行下拉刷新就在那个文件夹的json里面加上"enablePullD ...

  9. MYSQL中str_to_date函数的用法

    str_to_date(str,format) 函数的用法 str_to_date函数将str转化为日期型的数据,format表示转化后的格式. format参数格式: 常用: %Y  年 %m  月 ...

  10. Xamarin官方示例代码无法部署,提示已跳过部署解决方法

    最近利用Visual Studio 2017学习Android开发.主要是通过Xamarin官方的文档进行的.官方的入门指导提供了很多的示例代码.但是下载之后,调试运行的时候,总是无法部署到虚拟机上. ...