建议56:使用担任ISerializable接口更灵活地控制序列化过程
接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttribute、OnDeserializingAttribute、OnSerializedAttribute、OnSerializingAttribute、NoSerializable等特性不能完全满足自界说序列化的要求,那就需要担任ISerializable了。
以下是格局化器的事情流程:如果格局化器在序列化一个东西的时候,,发明东西担任了ISerializable接口,那它就会忽略失类型所有的序列化特性,转而挪用类型的GetObjectData要领来结构一个SerializationInfo东西,要领内部卖力向这个东西添加所有需要序列化的字段(“添加”这个词可能不太得当,因为我们在添加前可以随意措置惩罚这个字段)。以建议55中的例子为例,如果要为ChineseName结构对应的值,在类担任ISerializable接口的情况下,应该这样去实现:
class Program { static void Main() { Person liming = new Person() { FirstName = "Ming", LastName = "Li" }; BinarySerializer.SerializeToFile(liming, @"c:\", "person.txt"); Person p = BinarySerializer.DeserializeFromFile<Person>(@"c:\person.txt"); Console.WriteLine(p.FirstName); Console.WriteLine(p.LastName); Console.WriteLine(p.ChineseName); } } [Serializable] public class Person : ISerializable { public string FirstName; public string LastName; public string ChineseName; public Person() { } protected Person(SerializationInfo info, StreamingContext context) { FirstName = info.GetString("FirstName"); LastName = info.GetString("LastName"); ChineseName = string.Format("{0} {1}", LastName, FirstName); } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("FirstName", FirstName); info.AddValue("LastName", LastName); } }
序列化工具类:
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; } } }
View Code