Serialize a class |
|
|
/// <Summary> /// Serialization /// </Summary> /// <Param name = "MSG"> structure information </param> /// <Returns> </returns> Public static byte [] serialize (Object OBJ) { Iformatter informatter = new binaryformatter (); Memorystream STM = new memorystream (); Informatter. serialize (STM, OBJ );Byte [] buffer = STM. toarray (); STM. Close (); Return buffer; } /// <Summary> /// Deserialization /// </Summary> /// <Param name = "buffer"> serial data </param> /// <Returns> </returns> Public static object deserialize (byte [] buffer) { Memorystream stream = new memorystream (buffer ); Binaryformatter outformatter = new binaryformatter (); Object OBJ = outformatter. deserialize (Stream ); Stream. Close (); Return OBJ; } Remember to mark as serializable before that class declaration |
|
========================================================== ==========================================
What is serialization?
---.Net
The runtime environment 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, the public and private fields of the object and the name of the class (Package
Class assembly), and then write the byte stream into the data stream. When the object is deserialized, a copy identical to the original object will be created.
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 the stream can be written to a disk file or any other streaming target. To write this stream, you must use the serialize and deserialize methods in the classes that implement the iformatter interface.
The. NET Framework provides the following two classes:
I. binaryformatter
Binaryformatter
Use a binary Formatter for serialization. You only need to create an instance of the stream and formatting program to be used, and then call the serialize of the formatting Program
Method. The stream and the object instance to be serialized are provided to this call as parameters. All member variables (or even variables marked as private) in the class 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 that the 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 formatter and a stream for reading, and then let the formatter deserialize the object.
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
Before
We use binaryformatter to serialize a plane in binary format. It is easy to replace the previous example with soapformatter, which will be in XML format.
So it can have better portability. All you have to do is change the formatter in the above Code to soapformatter, while the serialize and
The call to deserialize remains unchanged. 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>
In
Note that the serializable attribute cannot be inherited. If
If a new class is derived, the new class must also be marked with this attribute; otherwise, the class cannot be serialized. 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 an implementation iformatter
Interface class, which is similar to soapformatter, but does not need any information. 2. Use xmlserializer, a class provided by the framework.
The differences between the xmlserializer class and the first two mainstream serialization classes are:
1. the serializable attribute is not required. The serializable and nonserializable attributes are ignored, but the xmlignore attributes are used, which is similar to the nonserializable attribute.
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 parameter
Xmlserializer object is specified
Connected to the class indicated by the type parameter. The xmlserializer class also has the serialize and deserialize methods:
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, using XML schemas, and soap encoding.
Custom serialization
For example
If you want to serialize the class but are not completely satisfied with the data stream organization mode, you can implement iserializable on the object.
Interface to customize the serialization process. This function is especially useful when the value of the member variable becomes invalid after deserialization, but you need to provide the value for the variable to recreate the complete state of the object. Except that the class must be declared
To implement the iserializable interface while serializable, you must implement getobjectdata
Method and a special constructor, which is used for deserializing objects. In the implementation of getobjectdata
The most commonly called serializationinfo method is addvalue. This method has an overloaded version for all standard types (INT, Char, and so on ).
Streamingcontext
Parameters describe the source and target of the given serialized stream, so that we can know whether we are serializing objects to persistent storage or serializing them across processes or machines. In deserialization, we call
Serializationinfo provides a set of getxxx methods that perform various inverse operations on all standard types of data against the overloaded version of addvalue. The following code example shows
How to Implement iserializable on the myobject class mentioned in the previous section.
[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 );
}
}
In
When getobjectdata is called during serialization, you need to fill in the serializationinfo provided in the method call.
Object. You only need to add the variable to be serialized in the form of name/value pairs. The name can be any text. As long as the serialized data is sufficient to restore the object during the deserialization process, you can freely choose to add
The member variable of serializationinfo. If the base object implements iserializable, the derived class should call
Getobjectdata method.
It must be emphasized that when adding iserializable to a class
Getobjectdata
And a special constructor with a specific prototype -- it is important that the parameter list of the constructor must be the same as that of getobjectdata. This constructor will use the following during deserialization:
The formatter deserializes data from the stream and then uses this constructor to list objects. 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
Serialization of A Class causes an exception. In terms of eliminating potential security and version control problems, the current design is better than the setobjectdata method. For example
If the setobjectdata method is defined as a part of an interface, this method must be a public method, so that you have to write code to prevent multiple calls.
Setobjectdata method. As you can imagine, if an object is performing some operations, but a malicious application calls the setobjectdata
Method will cause some potential troubles.
In the deserialization process, use the constructor provided for this purpose to serialize the serializationinfo
Passed to the class. When the object is deserialized, any visibility constraints on the constructor will be ignored. Therefore, classes can be marked as public, protected, internal, or
Private. 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
Private. To restore the object state, you only need to use the name used during serialization to retrieve the value of the variable from serializationinfo. If the base class implements
Iserializable, you should call the constructors of the base class so that the base object can restore its variables.
If a new class is derived from the class that implements iserializable, the constructor and the getobjectdata method must be implemented as long as the new class contains any variable to be serialized. 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 the complete object cannot be constructed after deserialization.
Pair
Such as being completely re-built, but calling methods in the deserialization process may bring adverse side effects, because the called methods may reference object references that are not deserialized at the call fashion. If reverse order is being performed
The column-based class implements ideserializationcallback. After deserializing the entire object chart, onserialization is automatically called.
Method. All referenced sub-objects are completely restored. Some classes do not use the above event listeners, so it is difficult to deserialize them. The hash is a typical example. Key to retrieval during deserialization
Word/value pairs are very easy. However, because classes derived from the hash list cannot be deserialized, some problems may occur when these objects are added to the hash list. Therefore, we recommend that you do not call
Method.
========================================================== ======================================
1. What is serialization?
Serialization is the process of converting the object state to a format that can be maintained or transmitted. During the serialization process, the public and private fields of the object and the name of the class (including the Assembly containing the class) are converted to byte streams and then written to the data stream. In contrast to serialization, deserialization converts a stream into an object. These two processes can be combined to easily store and transmit data.
2. Why serialization?
A. One reason is to keep the object state in the storage media so that you can recreate an exact copy later.
Me
You often need to save the field value of the object to the disk and retrieve the data later. Although this can be done without serialization, this method is often cumbersome and error-prone and requires object tracking.
It becomes more and more complex. Imagine writing a large business application that contains a large number of objects. programmers have to write code for each object to save fields and attributes to
Disk and restore these fields and attributes from the disk. Serialization provides a quick way to easily achieve this goal.
B. Another reason is that an object is sent from one application domain to another by using a 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 can also use serialization to pass objects from one application domain to another through values.
Public
Common Language Runtime (CLR) manages the distribution of objects in the memory,. net
The framework provides an automatic serialization mechanism by using reflection. After the object is serialized, the class name, assembly, and all data members of the class instance are written to the storage media. Objects are usually stored with member variables.
Instance reference. After the class is serialized, the serialization engine tracks all serialized reference objects to ensure that the same object is not serialized multiple times .. Net
The serialization architecture provided by the framework can automatically and correctly process object charts and circular references. The only requirement for object charts is that all objects referenced by objects being serialized must be marked
Serializable (see Basic serialization ). Otherwise, an exception occurs when the serialization program attempts to serialize unlabeled objects.
When deserializing A serialized class, the class is re-created and the values of all data members are automatically restored.
2. 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, but 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. Note that the serialized class must be public, otherwise it cannot be serialized.
To serialize the instance of this class to a file ?. Net Framework provides two methods:
A. 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)
B. 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 ();
4. How to serialize and deserialize custom visual controls in disguise
Custom Controls in winform are inherited from system. windows. form class, while form class is inherited from marshalbyrefobject, the form itself cannot be serialized, the form implementation is based on the Win32 GUI resources, 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 properties of the Control. to serialize the control, you only need to copy the instance of the control to the memory class, it is serialized to 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. You can continue to use some events and methods of controls.
WWF emphasizes class instantiation because the workflow and application are in different threads. To use a class as the carrier for data transmission between the two, the class must be defined as public serialization for binary transmission.