Source: From the Internet
Serialization can be defined as the process of storing the object state to the storage media. In this process, the public and private fields of the object are
And the class name (including the Assembly containing the class) are converted into byte streams, and then written into the data stream. When this object is "deserialized" in the future
Create an exact copy of the original object.
I. Why serialization?
One reason is to keep the object state in the storage media so that you can recreate a precise copy later;
Another reason is that an object is sent from one application domain to another by value.
For example, serialization can be used to save the session state in ASP. NET and copy the object to the clipboard of Windows Forms. Remote processing is also available
To use serialization to pass an object from one application domain to another by value.
Ii. How to Implement Object serialization and deserialization
To serialize an object, ensure that the object can be serialized. In addition, serialization only saves the object attributes effectively.
Some methods of the object cannot be serialized.
The easiest way to implement serializable class serialization is to add the serializable attribute tag class. For example:
[Serializable ()]
Public class meablock
{
Private int m_id;
Public String Caption;
Public meablock ()
{
/// Constructor
}
}
This class can be serialized.
To serialize the instance of this class to a file ?. Net Framework provides two methods:
1. XML serialization
Use the xmlserializer class to serialize the following items.
Public read/write attributes and fields of public classes
Class that implements icollection or ienumerable. (Note that only the set will be serialized, but the public attribute will not .)
Xmlelement object.
Xmlnode object.
DataSet object.
To serialize instances of the above classes, refer to the following example:
Meablock myblock = new meablock ();
// Insert code to set properties and fields of the object.
Xmlserializer myserializer = new xmlserializer (typeof (meablock ));
// To write to a file, create a streamwriter object.
Streamwriter mywriter = new streamwriter ("myfilename. xml ");
Myserializer. serialize (mywriter, meablock );
Note that XML serialization only saves public fields and does not save private fields.
The generated XML file format is as follows:
<Meablock>
<Caption> test </caption>
</Meablock>
The deserialization of objects is as follows:
Meablock myblock;
// Constructs an instance of the xmlserializer with the type
// Of object that is being deserialized.
Xmlserializer myserializer = new xmlserializer (typeof (meablock ));
// To read the file, creates a filestream.
Filestream myfilestream = new filestream ("myfilename. xml", filemode. Open );
// Callthe deserialize method and casts to the object type.
Myblock = (meablock) myserializer. deserialize (myfilestream)
2. binary serialization
Different from XML serialization, binary serialization can serialize all fields (both private and public) in the instance of the class.
. This makes it easier and more accurate to restore copies of objects.
To serialize instances of the above classes, refer to the following example:
Meablock myblock = new meablock ();
// Insert code to set properties and fields of the object.
Iformatter formatter = new binaryformatter ();
Stream stream = new filestream ("myfile. bin", filemode. Create, fileaccess. Write,
Fileshare. None );
Formatter. serialize (stream, myblock );
Stream. Close ();
The deserialization of objects is as follows:
Iformatter formatter = new binaryformatter ();
Stream stream = new filestream ("myfile. bin", filemode. Open, fileaccess. read,
Fileshare. Read );
Meablock myblock = (meablock) formatter. deserialize (Stream );
Stream. Close ();
3. How to serialize and deserialize custom visual controls in disguise
For custom controls in winform, the Form class inherits from the system. Windows. Form class, and
The format itself cannot be serialized. The implementation of the form is based on the GUI resources under Win32 and cannot be separated from the current context.
Of course, you can use a work und to serialize controls. The memory model is used here.
The definition memory class (actually a serializable entity class) is used to record the valid attributes of the Control. When you need to serialize the control, only
Copy the instance of the control to the memory class to serialize and save the memory class.
Deserialization is an inverse process. Deserializes data streams into the memory class, and generates control instances based on the attributes of the memory class. And
You can continue to use some events and methods of the control.
----------------------------------------
What is serialization?
The runtime environment of ---.net is used to support the streaming mechanism of user-defined types. It stores the status of the object instance to the stored media.
In this process, first convert the Public and Private fields of the object and the name of the class (including the Assembly where the class is located) into byte streams, and then convert the word
Throttle write data streams. When deserializing the object
Copies of identical objects.
Serialization objective:
1. Make the custom object persistent in a certain storage form;
2. transfer an object from one place to another.
Essentially, the serialization mechanism is to convert the class value into a general (that is, continuous) byte stream, and then you can write the stream to a disk file or any
Other streaming targets. To write this stream, we need to use the serialize and
Deserialize method.
The. NET Framework provides the following two classes:
I. binaryformatter
Binaryformatter uses a binary Formatter for serialization. You only need to create an instance of the stream and formatting program to use, and then
Call the serialize method of the formatter. The stream and the object instance to be serialized are provided to this call as parameters. All member variables in
To private variables) will be serialized.
First, create a class:
[Serializable]
Public class myobject {
Public int n1 = 0;
Public int n2 = 0;
Public String STR = NULL;
}
The serializable attribute explicitly indicates that the class can be serialized. Similarly, we can use the nonserializable attribute to explicitly indicate
Class cannot be serialized.
Then we create an instance of this class, serialize it, and save it to the file for persistence:
Myobject OBJ = new myobject ();
OBJ. n1 = 1;
OBJ. n2 = 24;
OBJ. Str = "some strings ";
Iformatter formatter = new binaryformatter ();
Stream stream = new filestream ("myfile. bin", filemode. Create,
Fileaccess. Write, fileshare. None );
Formatter. serialize (stream, OBJ );
Stream. Close ();
It is also very easy to restore an object to its previous state. First, create a formatting program and a stream for reading, and then set the formatting program
For deserialization.
Iformatter formatter = new binaryformatter ();
Stream stream = new filestream ("myfile. bin", filemode. Open,
Fileaccess. Read, fileshare. Read );
Myobject OBJ = (myobject) formatter. deserialize (fromstream );
Stream. Close ();
// The following is proof
Console. writeline ("N1: {0}", obj. N1 );
Console. writeline ("N2: {0}", obj. N2 );
Console. writeline ("str: {0}", obj. Str );
Ii. soapformatter
Previously, we used binaryformatter to serialize data in binary format. We can easily change the previous example to soapformatter.
This will be formatted in XML, so it can be more portable. All you have to do is replace the formatting program in the above Code
Soapformatter, while serialize and deserialize do not change. For the example used above, the formatter will generate the following results
.
<SOAP-ENV: Envelope
Xmlns: xsi = http://www.w3.org/2001/XMLSchema-instance
Xmlns: XSD = "http://www.w3.org/2001/XMLSchema"
Xmlns: Soap-ENC = http://schemas.xmlsoap.org/soap/encoding/
Xmlns: Soap-Env = http://schemas.xmlsoap.org/soap/envelope/
SOAP-ENV: encodingstyle =
Http://schemas.microsoft.com/soap/encoding/clr/1.0
Http://schemas.xmlsoap.org/soap/encoding"
Xmlns: A1 = "http://schemas.microsoft.com/clr/assem/ToFile">
SOAP-ENV: Body>
<A1: myobject id = "ref-1">
<N1> 1 </N1>
<N2> 24 </N2>
<STR id = "ref-3"> some strings </STR>
</A1: myobject>
SOAP-ENV: Body>
SOAP-ENV: envelope>
Note that the serializable attribute cannot be inherited. If a new class is derived from myobject, the new class
This attribute must also be used for marking; otherwise, serialization will fail. For example, if you try to serialize the following class instances,
Serializationexception indicates that the mystuff type is not marked as serializable.
Public class mystuff: myobject
{
Public int N3;
}
However, there is another question about the formatter. Suppose we only need XML, but we do not need the additional information unique to soap. What should we do?
There are two solutions:
1. Compile a class that implements the iformatter interface. The method is similar to soapformatter, but there is no information you don't need;
2. Use the xmlserializer class provided by the framework.
The differences between the xmlserializer class and the first two mainstream serialization classes are:
1. serializable and nonserializable attributes are ignored, but xmlignore attributes and
The nonserializable attribute is similar.
2. This class cannot securely access private members. Therefore, you must change Private Members to public members or provide appropriate public features.
3. The serialized class must have a default constructor.
Let's change the previous myobject class:
Public class myobject {
Public int N1;
Public String STR;
Public myobject (){}
Public myobject (N1, STR)
{
This. n1 = N1;
This. Str = STR;
}
Public override string tostring ()
{
Return string. Format ("{0 }:{ 1}", this. STR, this. N1 );
}
}
Now we use the xmlserializer class to serialize the modified myobject. Because the xmlserializer class constructor has a type
So the xmlserializer object is explicitly connected to the class indicated by this type parameter. The xmlserializer class also has serialize and
Deserialize method:
Myobject OBJ = new myobject (12, "some string ...");
Xmlserializer formatter = new xmlserializer (typeof (myobject ));
Stream stream = new filestream ("myfile. xml", filemode. Create,
Fileaccess. Write, fileshare. None );
Formatter. serialize (stream, OBJ );
// The following is deserialization.
Stream. Seek (0, seekorigin. Begin)
Myobject obj_out = (myobject) formatter. deserialize (Stream)
Stream. Close ();
Console. writeline (obj_out );
This simple column can be expanded to take advantage of more xmlserializer functions, including using attributes to control XML tags and using XML Schemas
And perform soap encoding.
Custom serialization
If you want to serialize the class but are not satisfied with the data stream organization mode, you can implement
The iserializable interface is used to customize the serialization process. This function is especially useful when the value of the member variable becomes invalid after deserialization, but it must be changed
To reconstruct the complete state of the object. Besides declaring the class as serializable, you must also implement the iserializable interface.
To implement the getobjectdata method and a special constructor, this constructor is used in deserialization of objects.
When the getobjectdata method is implemented, the most commonly called serializationinfo method is addvalue. This method has
The streamingcontext parameter describes the source and target of the given serialized stream, so that we can
To know whether the object is serialized to persistent storage or whether it is serialized across processes or machines. In deserialization, we call
Serializationinfo provides a set of getxxx methods.
Perform inverse operations on all standard types of data for various addvalue overloaded versions. The following code example shows how to use the myobject
Class to implement iserializable.
[Serializable]
Public class myobject: iserializable
{
Public int N1;
Public int N2;
Public String STR;
Public myobject ()
{
}
Protected myobject (serializationinfo info, streamingcontext context)
{
N1 = info. getint32 ("I ");
N2 = info. getint32 ("J ");
STR = info. getstring ("K ");
}
Public Virtual void getobjectdata (serializationinfo info,
Streamingcontext context)
{
Info. addvalue ("I", N1 );
Info. addvalue ("J", N2 );
Info. addvalue ("K", STR );
}
}
When calling getobjectdata during serialization, you need to fill in the serializationinfo object provided in the method call. Only by name
Add the variable to be serialized in the form of a/value pair. The name can be any text. As long as the serialized data is sufficient to be restored during the deserialization Process
Object, You can freely select the member variables added to serializationinfo. If the base object implements iserializable, the derived class should
Call the getobjectdata method of the base object.
It must be emphasized that when adding iserializable to a class, getobjectdata and special
Type constructor-it is important that the parameter list of the constructor must be the same as that of getobjectdata. This constructor will be deserialized
Use in the process: The formatter deserializes data from the stream, and then uses this constructor to implement real-name object listing. If
Getobjectdata, the compiler will issue a warning.
However, the constructor cannot be implemented forcibly, so no warning is given when the constructor is missing. If no constructor is available
If you try to deserialize a class, an exception will occur. In terms of eliminating potential security and version control problems, the current design is better than that of setobjectdata.
Method. For example, if you define the setobjectdata method as a part of an interface, the method must be a public method, which forces the user
Write code to prevent multiple calls to the setobjectdata method. As you can imagine, if an object is performing some operations and a malicious application process
Calling the setobjectdata method of this object in sequence will cause some potential troubles.
In the deserialization process, use the constructor provided for this purpose to pass serializationinfo to the class. During object deserialization
Any visibility constraints of the constructor are ignored. Therefore, classes can be marked as public, protected, internal, or private. I
A good way is to mark the constructor as protect if the class is not encapsulated. If the class has been encapsulated, it should be marked as private. Yes
Restore the object status. You only need to use the name used for serialization.
Name, the value of the variable is retrieved from serializationinfo. If the base class implements iserializable, you should call the constructor of the base class
The basic object can restore its variables.
If a new class is derived from the class that implements iserializable, as long as the new class contains any variable to be serialized, it must
The constructor and the getobjectdata method are also implemented. The following code snippet shows how to use the myobject class shown above to complete this operation.
.
[Serializable]
Public class objecttwo: myobject
{
Public int num;
Public objecttwo (): Base (){}
Protected objecttwo (serializationinfo Si, streamingcontext context): Base (Si, context)
{
Num = Si. getint32 ("num ");
}
Public override void getobjectdata (serializationinfo Si, streamingcontext context)
{
Base. getobjectdata (Si, context );
Si. addvalue ("num", num );
}
}
Remember to call the base class in the deserialization constructor. Otherwise, the constructor on the base class will never be called and will not be called after deserialization.
Method to build a complete object.
The object is completely re-built, but calling the method in the anti-serialization process may bring adverse side effects, because the called method may reference
In the call fashion, there is no deserialization of object reference. If the class being deserialized implements ideserializationcallback, The deserialization
The onserialization method is automatically called after the entire object chart is converted. All referenced sub-objects are completely restored. Some classes are not used
The above event listeners are difficult to deserialize them. The hash is a typical example.
In the deserialization process, it is very easy to retrieve the keyword/value pair. However, because the class derived from the hash list cannot be deserialized
Some problems may occur when these objects are added to the return list. Therefore, we recommend that you do not call methods on the hash table.