编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化
2015-08-17 00:07
525 查看
建议54:为无用字段标注不可序列化
序列化是指这样一种技术:把对象转变成流。相反过程,我们称为反序列化。在很多场合都需要用到这项技术。
把对象保存到本地,在下次运行程序的时候,恢复这个对象。
把对象传到网络中的另外一台终端上,然后在此终端还原这个对象。
其他场合,如:把对象赋值到系统的粘贴板中,然后用快捷键Ctrl+V恢复这个对象。
一下几个原因,决定了要为无用字段标注不可序列化:
节约了空间。类型在序列化后往往会存储到某个地方,如数据库、硬盘或内存中,如果一个字段在反序列化后不需要保持状态,那它就不应该被序列化,这会占用宝贵的空间资源。
反序列化后字段信息已经没有意义了。如Windows内核句柄,在反序列化后往往已经失去了意义,所以它就不应该被序列化。
字段因业务上的原因不允许被序列化。比如,明文密码不应该被序列化后一同保存在文件中。
如果字段本身所对应的类型在代码中未被设定成可序列化,那它就该被标注不可序列化,否则运行时会抛出SerializationException异常。
类型被添加Serializable特性后,默认所有的字段全部都能被序列化。如果部分字段不需要序列化,可以在该字段上应用NonSerialized特性。属性事实上是方法,所以是不能序列化的,自动属性也是如此。另外,要标识事件为不可序列化,需要用field: NonSerialized语法。
下面是一个序列化工具类:
实例代码:
输出:
Rose
21
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
序列化是指这样一种技术:把对象转变成流。相反过程,我们称为反序列化。在很多场合都需要用到这项技术。
把对象保存到本地,在下次运行程序的时候,恢复这个对象。
把对象传到网络中的另外一台终端上,然后在此终端还原这个对象。
其他场合,如:把对象赋值到系统的粘贴板中,然后用快捷键Ctrl+V恢复这个对象。
一下几个原因,决定了要为无用字段标注不可序列化:
节约了空间。类型在序列化后往往会存储到某个地方,如数据库、硬盘或内存中,如果一个字段在反序列化后不需要保持状态,那它就不应该被序列化,这会占用宝贵的空间资源。
反序列化后字段信息已经没有意义了。如Windows内核句柄,在反序列化后往往已经失去了意义,所以它就不应该被序列化。
字段因业务上的原因不允许被序列化。比如,明文密码不应该被序列化后一同保存在文件中。
如果字段本身所对应的类型在代码中未被设定成可序列化,那它就该被标注不可序列化,否则运行时会抛出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 = 21, 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个建议——建议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:即使提供了显式释放方法,也应该在终结器中提供隐式清理
- AutoCAD.Net/C#.Net QQ群:193522571 将坐标系置为WCS