Serialization in .NET

xiaoxiao2021-03-06  123

What is serialization? ---. Net runtime environment is used to support the fluidization of user-defined types. It is the process of storeing the status of the object instance to the storage medium. In this process, first convert the public field of the object and the private field and the name of the class (including the assembly of the class) into a byte stream, and then write the byte stream into the data stream. When the object is then reorganized, a copy of the same identical object is created.

Device for serialization: 1. Custom objects are held in a storage form; 2, the object is passed from one place to another.

Substant serialization mechanisms are converted to a general (ie continuous) byte stream, and then the stream can be written to disk files or any other fluidized target. To write this stream, you must use the Serialize and DeserialIze methods in classes that implement the IFORMATTER interface. Provide such two classes in the .NET framework:

First, binaryformatter

BinaryFormatter serializes the binary format. Simply create an instance of the stream and formatting program to use, then call the SERIALIZE method for the formatting program. The flow and the sequential object instance is supplied to this call as a parameter. All member variables in the class (or even variables marked as private) will be serialized.

First we create a class: [serializable] public class myObject {public int n1 = 0; public int N2 = 0; public string str = null;} The serializable property is used to explicitly indicate that the class can be serialized. Similarly, we can use the nonserializable attribute to clearly express classes that cannot be serialized. Then we create an instance of this class, then serialize, and save your lasting: 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 the object to it. First, create a formatting program and stream for reading, and then let the formatting procedure against objects. 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 to prove console.writeline ("N1: {0}", obj.n1); console.writeline ("N2: {0}", obj.n2); console.writeLine ("str: {0}" , obj.str);

Second, SOAPFORMATTER

As we use binaryformatter to serialize in binary format. It is easy for us to change the previous example to SOAPFormatter, which will be formatted in XML, so there is better portability. The changes you want to do are simply convert the formatted program in the above code to SOAPFORMATTER, while Serialize and DeserialIze calls unchanged. For examples used above, the formatter will generate the following results.

1 24 Some strings

It should be noted here that the serializable attribute cannot be inherited. If a new class is derived from MyObject, this new class must also mark this property, otherwise it will not be serialized. For example, if you try to serialize the following instance, a serializationException will appear, indicating that the MySTUFF type is not marked as sequential.

Public class mystuff: myObject {public int n3;}

However, there is a problem with the formatter, suppose we only need XML, but don't need SOAP unique information, then what to do? There are two options: 1. Write a class that implements the iFormatter interface, which is similar to SOAPFormatter, but can not have information you don't need; 2. Use the frames provided by the frame to use the class XMLserializer. Several differences from XMLSerializer classes and the first two mainstream serializations are: 1, no serializable properties, serializable and nonserializable properties will be ignored, but use the XMLIGNORE attribute, and the Nonserializable property is similar. 2. This class cannot secure access to private paragraphs, so learn private members to public members, or provide suitable public characteristics. 3. The class required to serialize has a default constructor.

We 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. Since there is a Type parameter in the constructor of the XMLSerializer class, the XMLSerializer object is clearly connected to the class represented by the TYPE parameter. XmlSerializer class Serialize and Deserialize method also has: MyObject obj = new MyObject (12, "some string ..."); XmlSerializer formatter = new XmlSerializer (typeof (MyObject)); Stream stream = new FileStream ( "MyFile.xml", FileMode .Create, fileaccess.write, Formatter.Serialize (stream, obj); // below is the anti-sequence-of-sequence stream.seek (0, seekorigin.begin) MyObject obj_out = (myObject) Formatter.deSerialize (stream) stream.close (); console.writeLine (obj_out);

This simple list can be extended in order to use more XMLSerializer features, including the use of attribute control XML tags, using XML mode and SOAP encoding. Custom Series If you want users to realize serialization on classes, the organization of data streams is not fully satisfied, and can be defined from the defined serialization process by implementing the iSerializable interface on the object. This feature is especially useful when the value of the member variables after the deserialization, but needs to provide a value for the variable to rebuild the full state of the object. In addition to the implementation of the classes to be SERIALIZABLE, you have to implement the iSerializable interface, you need to implement the getObjectData method and a special constructor, and use this constructor when the object is reversed. When implementing the getObjectData method, the most frequently called SerializationInfo method is AddValue, which has overloaded version of all standard types (int, char, etc.); and the streamingContext parameter describes the source and target of a given serialization. This way we can know that we are serializing the object to persistence storage or serialize them across processes or machines. When it is reverse selecinstened, we call a set of GetXXxx methods provided by SerializationInfo, and they perform inverse operations of various AddValue overload versions for all standard type data. The following example shows how to implement iSerializable on the MyObject class mentioned in the previous part.

[Serializable] public class myObject: iSerializable {public int n1; public int n2; public string STR Download Adobe Reader: PUBLIC STRIA

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, The SerializationInfo object provided in the method call is required. Simply add a variable that will be serialized in the form of name / value. Its name can be any text. As long as the serialized data is sufficient to restore the object during the reverse sequence, it is possible to freely select the member variable added to the SerializationInfo. If the base object implements iSerializable, the derived class should call the GetObjectData method for its base object.

It is important to emphasize that when adding iSerializable to a class, you need to implement GetObjectData and special-specific constructor with specific prototypes - it is important that the parameter list of this constructor must be the same as getObjectData, this constructor will be Use in the reverse sequence of sequences: The formatter is deserialized from the stream, and then the object is subjected to the object through this constructor. If you lack getObjectData, the compiler will issue a warning. However, since the constructor cannot be enforced, a warning will not be issued when the constructor is missing. If you try to deactivate a certain class without constructuring, an exception will occur. The current design is better than the SetObjectData method in eliminating potential security and version control issues. For example, if the setObjectData method is defined as part of an interface, this method must be a public method, which makes the user have to write code to prevent multiple calling setObjectData methods. You can imagine that if an object is performing some operations, and a malicious application calls the SETOBJECTDATA method for this object, it will cause some potential trouble.

During the reverse selecente process, the constructor provided for this purpose is passed to the class. When an object is reverse selecinstened, any visibility constraint for the constructor will be ignored, so the class is marked as public, protected, internal, or private. A nice way is to mark the constructor as protecty in the case where the class is not encapsulated. If class is packaged, it should be marked as private. To restore the status of the object, simply use the name when serialization, retrieve the value of the variable from the SerializationInfo. If the base class implements iSerializable, the constructor of the base class should be called so that the base object can restore its variables.

If a new class is generated from the class that implements the iSerializable class, the constructor must be implemented simultaneously as long as the new class contains any variables that require sequentialization. The following code snippet shows how to use the MyObject class shown above to complete this.

[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 reverse sequence constructor, otherwise, Never call the constructor on the base class, and the complete object cannot be built after the reverse sequence is.

Objects are thoroughly rebuilt, but the modification of the method may bring poor side effects during the reverse system, because the way to be called may reference object references that are not retrogradened in the call. If you are performing an anti-sequence-based class implementing IDSerializationCallback, the ONSERIALIZATION method will be automatically called after the entire object chart is reserved. At this time, all sub-objects referenced are completely reduced. Some classes do not use the above event listeners, it is difficult to deserialize them, and the hash table is a typical example. Retrieving keywords / values ​​in the reverse selecente process is very easy, however, since the classes produced from the hash beta have been reversed, some problems will occur when they add these objects. Therefore, it is recommended not to call the method on the hash table.

转载请注明原文地址:https://www.9cbs.com/read-125866.html

New Post(0)