建议54:为无用字段标注不可序列化

序列化是指这样一种技术:把对象转变成流。相反过程,我们称为反序列化。在很多场合都需要用到这项技术。

  • 把对象保存到本地,在下次运行程序的时候,恢复这个对象。
  • 把对象传到网络中的另外一台终端上,然后在此终端还原这个对象。
  • 其他场合,如:把对象赋值到系统的粘贴板中,然后用快捷键Ctrl+V恢复这个对象。

一下几个原因,决定了要为无用字段标注不可序列化:

  1. 节约了空间。类型在序列化后往往会存储到某个地方,如数据库、硬盘或内存中,如果一个字段在反序列化后不需要保持状态,那它就不应该被序列化,这会占用宝贵的空间资源。
  2. 反序列化后字段信息已经没有意义了。如Windows内核句柄,在反序列化后往往已经失去了意义,所以它就不应该被序列化。
  3. 字段因业务上的原因不允许被序列化。比如,明文密码不应该被序列化后一同保存在文件中。
  4. 如果字段本身所对应的类型在代码中未被设定成可序列化,那它就该被标注不可序列化,否则运行时会抛出SerializationException异常。

类型被添加Serializable特性后,默认所有的字段全部都能被序列化。如果部分字段不需要序列化,可以在该字段上应用NonSerialized特性。属性事实上是方法,所以是不能序列化的,自动属性也是如此。另外,要标识事件为不可序列化,需要用field: NonSerialized语法。

下面是一个序列化工具类:

    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;
}
}
}

实例代码:

    class Program
{
static void Main()
{
Person mike = new Person() { Age = , Name = "Mike" };
mike.NameChanged += new EventHandler(mike_NameChanged);
BinarySerializer.SerializeToFile(mike, @"c:\", "person.txt");
Person p = BinarySerializer.DeserializeFromFile<Person>(@"c:\person.txt");
p.Name = "Rose";
Console.WriteLine(p.Name);
Console.WriteLine(p.Age.ToString());
} static void mike_NameChanged(object sender, EventArgs e)
{
Console.WriteLine("Name Changed");
}
} [Serializable]
class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
if (NameChanged != null)
{
NameChanged(this, null);
}
name = value;
}
} public int Age { get; set; } [NonSerialized]
private Department department;
public Department Department
{
get
{
return department;
}
set
{
department = value;
}
} [field: NonSerialized]
public event EventHandler NameChanged;
}

输出:

Rose
21

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

编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化的更多相关文章

  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. [转]Mac上的抓包工具Charles

    $*********************************************************************************************$ 博主推荐 ...

  2. 服务端获得客户端ip

    /** * 获取客户端ip地址(可以穿透代理) * * @param request * @return */ public static String getRemoteAddr(HttpServl ...

  3. PTA 最大子列和问题(10 分)

    最大子列和问题(10 分) 给定K个整数组成的序列{ N​1​​, N​2​​, ..., N​K​​ },“连续子列”被定义为{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤ ...

  4. Train-Alypay-Cloud:蚂蚁金融云知识点

    ylbtech-Train-Alypay-Cloud:蚂蚁金融云知识点 1.返回顶部 1. 1.数据库与缓存结合使用https://www.cloud.alipay.com/docs/2/47337 ...

  5. MVC 公共类App_Code不识别

    .Net MVC需要写公共类的时候 右击添加 App_Code 文件夹,新建类—>右击类—>属性,生成操作 —>选择 —>编译 .net MVC项目本身是个应用程序,所以其实不 ...

  6. ILMerge最佳实践

    背景 为了生成的代码更加简捷,复制方便,常常会把多个可执行文件合并成一个. 方案 Project=>Properties=>Build Events=>Edit Post-build ...

  7. 初识 Julia

    Ubuntu 下安装 Julia 环境 sch01ar@ubuntu:~$ sudo apt install julia 安装完成后打开 Julia 的交互式会话 sch01ar@ubuntu:~$ ...

  8. spring-boot多环境配置文件

    spring-boot多环境配置文件 目录 配置 多环境配置文件名称要遵循格式 application-{profile}.yml application.yml spring: profiles: ...

  9. 3.solr学习速成之索引添加 查询 删除

    solrserver.java public class solrServer { private solrServer(){}; final static String SOLR_URL = &qu ...

  10. Android 4 学习(14):Internet Resources

    参考<Professional Android 4 Development> 使用Internet资源 打开URI String myFeed = getString(R.string.m ...