157 suggestions for writing high-quality code to improve C # programs-recommendation 55: reduce serializable fields by using custom features,
Recommendation 55: use custom features to reduce serializable Fields
Attribute can be declared to add comments to the target element in the code. During running, you can query metadata information in these managed blocks to change the running behavior of the target element. The System. Runtime. Serialization namespace has four such features:
- OnDeserializedAttribute: when applied to a method, this method is called immediately after the object is deserialized.
- OnDeserializingAttribute. when applied to a method, this method is called when the deserialization object is specified.
- OnSerializedAttribute: when it is applied to a method, it is specified to call this method immediately after Object serialization.
- OnSerializingAttribute. when applied to a method, this method is called when the object is serialized.
With these features, you can process serialization and deserialization more flexibly. For example, we can use this to further reduce some serializable fields.
The Person class consists of the ChineseName, FirstName, and LastName fields:
[Serializable] class Person { public string FirstName; public string LastName; public string ChineseName; }
We know that ChineseName can be inferred from FirstName and LastName, which means that ChineseName does not need to be serialized. At this time, we can use the feature to provide a method to calculate the value of ChineseName after serialization:
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); } }
Serialization tool class:
Public class BinarySerializer {// Serialize the type to a string 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 () ;}}// serialize the type to public static void SerializeToFile (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 () ;}// Deserialize the string to 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; }}// Deserialize the object to 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 ;}}}