Source: PConline
Responsible editor: ycx
[03-5-29 10:27]
Author: sam1111/ASPCool
Abstract: This article briefly introduces the Serialization concept in. NET and the method for implementing Serialization in code. At the end of this article, we will introduce the use of Serialization in the Clone method.
Serialization Concept
Serialization is an implementation in. NET.Object Persistence Mechanism. It is a process of converting the data in an object into a single element (usually Stream. Its Inverse Process is Deserialization. The core concept of Serialization is to regard all the data of an object as an independent unit.
In general, Serialization is required in two cases: 1) when we want to completely Save the current state of the object to the storage medium, so that we can accurately restore the object in the future; 2) When we want to pass an object from an Application domain to another Application space. For example, the Windows Form program uses the Serialization mechanism to copy and paste the clipboard.
. NET Framework supports two types of Serialization: Shallow Serialization and Deep Serialization.
The so-calledShallow Serialization converts the value of the read-write attribute of an object to the word throttling, while the data inside the object (data not exposed through the read-write attribute) is not converted. XmlSerializer and Web Services use this technology.
Deep Serialization is more thorough than Shallow Serialization because it copies the actual values stored in the object's private variables to the byte stream.AndDeep Serialization also serialize the entire object graph. That is to say,If your object holds a reference to another object or a set referenced by another object, all these objects will be Serialize.BinaryFormatter, SoapFormatter, And. NET Remoting both use the Deep Serialization technology. It is even used for LosFormatter to generate State data stored on the Web Form page.
This article focuses on Deep Serialization.
Serialization Process
. NET Framework provides automatic Serialization through Reflection. When an object is Serialized, its class name, Assembly, and all data members of the class instance are written to the storage media. The Serialization engine keeps track of all serialized object references to ensure that the same object references are serialized at most once.
Generally, a Serialization process is triggered by the Serialize method of formatter (such as BinaryFormatter. The object Serialization process follows the following rules:
1. Check whether the formatter has a proxy selector ). If yes, check whether the proxy selector holds the given object type. If yes, ISerializable. GetObjectData is called.
2. If formatter does not have a proxy selector or the proxy selector does not have an object type, check whether the object is marked with the Serializable attribute. If no, a SerializationException is thrown.
3. If the object is marked as Serializable, check whether the object has implemented the ISerializable interface. If this interface is implemented, GetObjectData is called.
4. If the object does not implement the ISerializable interface, use the default serialization policy to serialize the domain not marked by the NonSerialized attribute.
Enable your class to be serialized
Through the analysis of the Serialization process, we can see that there are two ways to enable a class to be serialized: 1) mark this class as Serializable; 2) this class implements the ISerializable interface and marks this class as Serializable.
1. Mark the Serializable attribute
Marking the Serializable attribute is the basic method for Serialization. A simple example:
[Serializable]
Public class Person
{
Public string name = null;
Public int age = 0;
}
You can use BinaryFormatter to serialize the above class:
Person sam = new Person ();
Sam. name = "sam ";
Sam. age = 24;
IFormatter formatter = new BinaryFormatter ();
Stream stream = new FileStream ("sam. dat ",
FileMode. Create, FileAccess. Write, FileShare. None );
Formatter. Serialize (stream, sam );
Stream. Close ();
It's that simple.You must create a Stream and a formatter instance.,Then call the Serialize method of formatter.. The data passed through BinaryFormatter serialize can still be returned through BinaryFormatter deserialize. The method is as simple as serialize, so we will not go into details here.
If you do not want to serialize all the fields in the class, you can use the NonSerialized attribute for selection. For example:
[Serializable]
Public class Person
{
Public string name = null;
[NonSerialized]
Public int age = 0;
}
In this way, the age domain will not be serialized.
Note that the Serializable attribute cannot be inherited. That is to say, if you want the derived class of Person to be Serialize, the derived class must also be marked by Serializable. Otherwise, the SerializationException is returned.
Similarly, all references to other classes in the Person class should be Serialize .. Most classes in the. NET Framework implement the ISerializable interface, but some classes are not implemented, such as ImageList.You can use the MSDN Library to go to a list of classes that implement the ISerializable interface. Be careful when using classes that do not implement this interface.
2. Implement the ISerializable Interface
The Serializable attribute is very powerful, which makes Serialize and Deserialize very simple. But there are some advantages and disadvantages in everything. The automatic serialization method implemented by Serializable is sometimes not flexible enough. We cannot fully control the behavior of Serialize and Deserialize, and sometimes their behavior is very important to us. So how can we control the behavior of Serialize and Deserialize? The answer is to implement the ISerializable interface by yourself.The ISerializable interface gives us greater freedom to control Serialize and Deserialize, but we will undoubtedly have to write more code L.
The following describes how to implement the ISerializabe interface. The ISerializable interface is located in the System. Runtime. Serialization namespace. The declaration is as follows:
Public inferface ISerializable
{
Void GetObjectData (SerializationInfo info,
StreamingContext context );
}
It only has one GetObjectData method. Therefore, we must implement this method just like other interfaces. HoweverDifferent from other interfaces, for Deserialization, we must also implement a special Constructor (I call this constructor "serialization constructor "), this constructor has the same parameter list as GetObjectData.. Since this constructor is used exclusively for the Reflection mechanism of. NET Framework in Deserialize, we usually declare it as a protected or private mode. (Of course, if your class only needs Serialize and does not need Deserialize, you can also not implement this special constructor)
[Serializable]
Public class Person: ISerializable
{
Public string name = null;
Public int age = 0;
Public Person ()
{
}
Protected Person (SerializationInfo, StreamingContext context)
{
Name = info. GetString ("name ");
Age = info. GetInt32 ("age ");
}
Void ISerializable. GetObjectData (SerializationInfo info,
StreamingContext context)
{
Info. AddValue ("name", name );
Info. AddValue ("age", age );
}
}
By implementing the ISerializable interface, we have the opportunityControl Serialize behavior in ISerializable. GetObjectData, and control Deserialize behavior in "serialization constructor". This interface provides us with comprehensive and flexible information, so that we can even play tricks in these two methods. For example, we can change info. FullTypeName in Deserialize to get another object of different types than the object to be Serialize.
Innovation
We have talked about the typical environment used by Serialization. It is an area involving Object persistence, such as Object Storage and inter-process data transmission. But in fact, it can also be applied to many other places. The key is whether we can think of using Serialization. Sometimes the mindset is terrible. For example, we can see how to use Serialization [1] In the Clone method.
If we want to implement the Clone method for the Person class, we usually write as follows:
[Serializable]
Public class Person: ICloneable
{
Public string name = null;
Public int age = 0;
Public object Clone ()
{
Person person = new Person ();
Person. name = name;
Person. age = age;
Return person;
}
}
If we use the Serialization method, the Clone function can be written as follows:
Public object Clone ()
{
MemoryStream stream = new MemoryStream ();
BinaryFormatter formatter = new BinaryFormatter ();
Formatter. Serialize (stream, this );
Stream. Position = 0;
Return formatter. Deserialize (stream );
}
From the two implementations, the use of Serialization to implement the Clone method does not seem to be of any benefit. However, if you are facing a complex class inheritance system, you must implement the Clone method from the base class to the derived class. With the first implementation method, you will have to write a Clone method for each class, and as the number of data members increases, this method will become longer and longer, in addition, errors may occur due to changes in data members (I have encountered several times that the member variables are added to the class, but the Clone method is not updated in time, resulting in running errors. It is difficult to debug such errors ). Now you can see the advantages of Serialization implementation? Yes, we only need to declare the Clone method as virtual in the base class and implement it using the Serialization method, and then ensure that the base class and derived class can be Serialize, isn't all the above troubles solved?
Summary
In modern software projects, no matter what kind of project will involve the problem of Object Persistence more or less ,. NET is no exception, whether it is Windows Form, ASP. both NET and Web Services need to process Object persistence. Serialization is the solution provided by. NET to solve this problem.
References
· [1] Rockford Lhotka, Object Serialization in Visual Basic. NET, and MSDN Library. The use of Serialization in the Clone method comes from this article.
· Piet Obermeyer and Jonathan Hawkins, Object Serialization in the. NET Framework, and MSDN Library.
· Jeffrey Richter, Part 1, Part 2, Part 3, and MSDN Library in. NET Run-time Serialization.