Binary Serialization

Why would you want to use serialization? The two most important reasons are to persist the state of an object to a storage medium so an exact copy can be re-created at a later stage, and to send the object by value from one application domain to another. For example, serialization is used to save session state in ASP.NET and to copy objects to the Clipboard in Windows Forms. It is also used by remoting to pass objects by value from one application domain to another.

persist storage

It is often necessary to store the value of the fields of an object to disk and then, later, retrieve this data. Although this is easy to achieve without relying on serialization, this approach is often cumbersome and error prone, and becomes progressively more complex when you need to track a hierarchy of objects. Imagine writing a large business application, that contains thousands of objects, and having to write code to save and restore the fields and properties to and from disk for each object. Serialization provides a convenient mechanism for achieving this objective.

The common language runtime manages how objects are stored in memory and provides an automated serialization mechanism by using reflection. When an object is serialized, the name of the class, the assembly, and all the data members of the class instance are written to storage. Objects often store references to other instances in member variables. When the class is serialized, the serialization engine tracks referenced objects, already serialized, to ensure that the same object is not serialized more than once. The serialization architecture provided with the .NET Framework correctly handles object graphs and circular references automatically. The only requirement placed on object graphs is that all objects, referenced by the serialized object, must also be marked as Serializable (for more information, see Basic Serialization). If this is not done, an exception will be thrown when the serializer attempts to serialize the unmarked object.

The easiest way to make a class serializable is to mark it with the Serializable attribute as follows.

[Serializable]

public class MyObject {

  public int n1 = 0;

  public int n2 = 0;

  public String str = null;

}

The code example below shows how an instance of this class can be serialized to a file.

MyObject obj = new MyObject();

obj.n1 = 1;

obj.n2 = 24;

obj.str = "Some String";

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);

formatter.Serialize(stream, obj);

stream.Close();

Marshal By Value

Objects are valid only in the application domain where they are created. Any attempt to pass the object as a parameter or return it as a result will fail unless the object derives from MarshalByRefObject or is marked as Serializable. If the object is marked as Serializable, the object will automatically be serialized, transported from the one application domain to the other, and then deserialized to produce an exact copy of the object in the second application domain. This process is typically referred to as marshal-by-value.

When an object derives from MarshalByRefObject, an object reference is passed from one application domain to another, rather than the object itself. You can also mark an object that derives from MarshalByRefObject as Serializable. When this object is used with remoting, the formatter responsible for serialization, which has been preconfigured with a surrogate selector (SurrogateSelector), takes control of the serialization process, and replaces all objects derived from MarshalByRefObject with a proxy. Without the SurrogateSelector in place, the serialization architecture follows the standard serialization rules described in Steps in the Serialization Process.

Steps In Serialization Process

When the Serialize method is called on a formatter, object serialization proceeds according to the following sequence of rules:

  • A check is made to determine whether the formatter has a surrogate selector(1). If the formatter does, check whether the surrogate selector handles objects of the given type. If the selector handles the object type,ISerializationSurrogate(the original string here in MSDN is "ISerializable". I believe MSDN team make a mistake something.should be ISerializationSurrogate).GetObjectData is called on the surrogate selector.

  • If there is no surrogate selector or if it does not handle the object type, a check is made to determine whether the object is marked with the Serializable(2) attribute. If the object is not, a SerializationException is thrown.

  • If the object is marked appropriately, check whether the object implements the ISerializable(3) interface. If the object does, GetObjectData is called on the object.

  • If the object does not implement ISerializable, the default serialization policy is used, serializing all fields not marked as NonSerialized.

 

你可能感兴趣的:(serialization)