Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / MS Press - Msdn Training Programming Net Framework With C#

.pdf
Скачиваний:
175
Добавлен:
12.02.2016
Размер:
16.87 Mб
Скачать

Module 12: Serialization

1

 

 

 

Overview

Topic Objective

To provide an overview of the module topics and objectives.

Lead-in

In this module, you will learn about serialization and learn how to write an application that serializes and deserializes an object graph by using a binary or SOAP XML format.

!Serialization Scenarios

!Serialization Attributes

!Object Graph

!Serialization Process

!Serialization Example

!Deserialization Example

!Custom Serialization

!Custom Serialization Example

!Security Issues

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Serialization is the process of converting a graph of objects into a linear sequence of bytes. That sequence of bytes can be sent elsewhere, for example, to a remote computer, and be deserialized, thereby making a clone in the remote memory of the original graph of objects.

After completing this module, you will be able to:

Write an application that serializes and deserializes an object graph by using either a binary or Simple Object Access Protocol (SOAP) XML format.

2Module 12: Serialization

Serialization Scenarios

Topic Objective

To show how serialization is used.

Lead-in

Serialization is used in some very common scenarios, such as persisting a graph of objects to disk or to objects in another process.

!Persistence

"Store and retrieve a graph of objects to and from a file

!Remoting

"Pass by value arguments that are transmitted between processes

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Serialization is used in some very common scenarios, such as persisting a graph of objects to disk or to objects in another process. The Microsoft® .NET Framework provides support for serialization and deserialization.

Persistence

Consider a simple single-user desktop application, such as a two-dimensional drafting package that is built by using object-oriented techniques. In such an application, a drawing is composed of different kinds of graphical objects of various types. The application represents the drawing as a graph of in-memory objects. One object represents the root of the entire picture. For example, a simple round table could be represented by a graph that consists of a root object that is an instance of a circle class. This instance of the circle class has four children that are each instances of a line class.

To save the entire drawing to a disk file so the drawing can be restored after rebooting the computer, you could force each class to implement a serialize and corresponding deserialize method. However, this approach is a potentially burdensome task for the application programmer.

Serialization in the .NET Framework

The .NET Framework common language runtime reduces the amount of work that is involved in serialization. At run time, the common language runtime maintains metadata that allows serialization code to discover the types and values of all fields and properties that make up any object. Using the common language runtime, an application requires only a few lines of code to serialize a object, such as the drawing described in the preceding paragraphs, and write it to a file, or to deserialize such a file into an in-memory graph of objects.

Module 12: Serialization

3

 

 

 

Remoting

In distributed computing, objects in one process may need to communicate with objects in another process. In the .NET Framework, the term remoting is typically used to refer to the process in which an object invokes a method in another object that is not in the same application domain. If the remote method takes as one of its arguments an object that lies at the root of a graph of objects, and if all of the objects in the graph are marked as remote-by-value, you must serialize a copy of the object graph and pass the graph to the remote object. The remote object must then deserialize the argument into an in-memory graph of objects.

For more information about remoting, see Module 13, “Remoting and Web Services,” in Course 2349B, Programming with the Microsoft .NET Framework (Microsoft Visual C# .NET).

4Module 12: Serialization

Serialization Attributes

Topic Objective

To explain how to mark a class with serialization attributes in C#.

Lead-in

If you are writing a class, you should be aware of serialization.

! To Mark a Class, Use Serializable Attribute

[Serializable] public class MyClass {} [Serializable] public class MyClass {}

! To Skip Specified Members, Use NonSerialized Attribute

[Serializable] public class MyClass { [Serializable] public class MyClass {

[NonSerialized] int _cashSize; [NonSerialized] int _cashSize;

//...

}}

//...

!To Provide Custom Serialization, Implement ISerializable

*****************************ILLEGAL FOR NON-TRAINER USE******************************

If you are writing a class, you should be aware of serialization. The common language runtime’s serialization services are built with the assumption that a type is not serializable unless the type is specifically marked as serializable. In the simplest case, all you need to do is mark a class as serializable because the runtime metadata understands everything about each object’s layout in memory, and its field and property definitions.

To mark a type as serializable in C#, you use the Serializable attribute, which is a reserved custom attribute. All fields in classes with this attribute are serialized, even private fields.

In the following example, MyClass is marked as serializable:

[Serializable] public class MyClass {}

For slightly more complex classes that have state that is invalid to serialize, the runtime provides support for marking those fields and properties as transient. For example, the following code uses the NonSerialized attribute to ensure that the _cashSize member of MyClass is not serialized:

[Serializable] public class MyClass

{

[NonSerialized] int _cashSize; //...

}

The small set of classes that need to participate in their own serialization and deserialization can provide a custom implementation of the ISerializable interface. For more information about custom serialization, see Custom Serialization in this module.

Module 12: Serialization

5

 

 

 

Object Graph

Topic Objective

To define an object graph and explain its function.

Lead-in

An object graph is a set of objects that share a set of references to each other.

3

Dog

4

Cat

7

Duck

1

Mouse

 

 

7

 

1

 

99

Horse

2

Duck

*****************************ILLEGAL FOR NON-TRAINER USE******************************

An object graph is a set of objects with references to each other. Serialization must provide a way to represent the links between the graph’s objects in the serialized stream that is created in the serialization process.

Understanding Object Graphs

Serialization of an object graph must provide a way to represent the links between the graph’s objects in the serialized stream that it creates. The value that is held in the field of the in-memory object, which links to another object, is essentially a 32-bit address. This address has meaning only in the owner address space and may change during garbage collection. Therefore, serialization must allocate a unique number to each object in the stream.

The illustration in the slide shows a graph of animal objects. Each object is represented as a box with its identification number inside the box and its class name to the right of the box.

You can represent the graph of objects that is shown in this illustration with a serialized stream, as in the following example:

Dog, 3, ref4, ref7, ref1 || Cat, 4, ref9 || Duck, 7 || Mouse, 1, ref9, ref2 || Horse, 9, ref4 || Duck, 2

The order in which you stream out the objects does not matter, nor does it matter what numbers you assign to the objects. What does matter is that no two objects are assigned the same number. The object numbers are significant only within a serialized stream. They are simply a way to represent the graph topology and to allow you to reconstruct a copy of that graph, perhaps on another computer.

6Module 12: Serialization

Tracking Object References

An algorithm that visits objects one at a time clearly must keep track of which objects it has already visited, for example, by using an internal list. Without due care, the algorithm may incorrectly serialize or deserialize an object graph.

For example, in the object graph in the illustration, to avoid entering an infinite loop, you must detect the cycle in the graph that occurs because of the mutual references between Cat 4 and Horse 9. During serialization, you must note that the Cat 4 that is linked to by Dog 3 is the same Cat 4 that is linked to by Horse 9 to ensure that deserialization will result in both Dog 3 and Horse 9 referring to the same Cat 4 object and not to two different copies.

Module 12: Serialization

7

 

 

 

Serialization Process

Topic Objective

To introduce the classes that are used in the serialization process.

Lead-in

The process of serializing an object graph involves identifying the individual objects in the graph and the relationships between them.

!Classes Used by the Default Serialization Process

"ObjectIDGenerator – generates IDs for objects

"ObjectManager – tracks objects as they are being deserialized

!Examples of Classes Used with Serialized Streams

"FileStream, MemoryStream, NetworkStream

!Formatter Class

"Writes or reads data in a specified format to the output or input streams

"Runtime provides BinaryFormatter and SoapFormatter

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The process of serializing an object graph involves identifying the individual objects in the graph and the relationships between them.

Classes Used by the Default Serialization Process

To create and track object ID numbers, serialization uses several classes, as follows:

!ObjectIDGenerator

The ObjectIDGenerator class generates IDs for objects. It keeps track of objects that have already been seen, so when you ask for the ID of an object, the ObjectIDGenerator knows whether to return the existing ID, or to generate, and remember, a new ID.

!ObjectManager

The ObjectManager class keeps track of objects as they are being deserialized. During deserialization, queries are made to the ObjectManager to determine whether a reference to an object that is in the serialized stream refers to an object that has already been deserialized or to an object that has not yet been deserialized. A reference to an object that has already been deserialized is called a backward reference. A reference to an object that has not yet been serialized is called a forward reference.

8Module 12: Serialization

Both the ObjectIDGenerator and ObjectManager classes are pluggable, so you can build your own alternatives.

Note During deserialization, fields are returned in the order in which they are returned from reflection. Reflection does not guarantee that it will follow metadata ordering.

You can serialize to many different kinds of streams, for example, to a

FileStream, a MemoryStream, or a NetStream. The serialized stream’s format is determined by the formatter object that you instantiate.

The .NET Framework runtime provides the following formatter classes:

!BinaryFormatter

The BinaryFormatter class is used for a compact binary representation.

!SoapFormatter

The SoapFormatter class is used for an XML representation.

Because formatters are pluggable, you can also build your own formatters.

Module 12: Serialization

9

 

 

 

Serialization Example

Topic Objective

To provide an example of serialization of an object graph.

Lead-in

This code sample shows how to perform default serialization of a graph of objects, whose root is an

ArrayList.

class SerializeExample{ class SerializeExample{

public static void Main(String[] args) { public static void Main(String[] args) {

// create the object graph // create the object graph

ArrayList l = new ArrayList(); ArrayList l = new ArrayList(); for (int x=0; x< 100; x++) { for (int x=0; x< 100; x++) {

}}

l.Add (x); l.Add (x);

// create the filestream // create the filestream

FileStream s = File.Create("foo.bin");

FileStream s = File.Create("foo.bin"); // create the BinaryFormatter

// create the BinaryFormatter BinaryFormatter b = new BinaryFormatter(); BinaryFormatter b = new BinaryFormatter(); // serialize the graph to the stream

// serialize the graph to the stream b.Serialize(s, l);

}}

}}

b.Serialize(s, l); s.Close(); s.Close();

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The following code sample shows how to perform default serialization of a graph of objects, whose root is an ArrayList. The serialized stream is written to a FileStream in binary format.

using System; using System.IO;

using System.Collections;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

class SerializeExample

{

public static void Main(String[] args)

{

//create the object graph ArrayList l = new ArrayList(); for (int x=0; x< 100; x++)

{

l.Add (x);

}

//create the filestream

FileStream s = File.Create("foo.bin");

//create the BinaryFormatter BinaryFormatter b = new BinaryFormatter();

//serialize the graph to the stream b.Serialize(s, l);

s.Close();

}

}

// open the filestream // open the filestream
FileStream s = File.OpenRead("foo.bin"); FileStream s = File.OpenRead("foo.bin");
// create the formatter // create the formatter
BinaryFormatter b = new BinaryFormatter(); BinaryFormatter b = new BinaryFormatter(); // deserialize
// deserialize
ArrayList p = (ArrayList) b.Deserialize(s); ArrayList p = (ArrayList) b.Deserialize(s); s.Close();
s.Close();
// print out the new object graph // print out the new object graph
// see module text for PrintValues’ code // see module text for PrintValues’ code PrintValues(p);
PrintValues(p);

10

Module 12: Serialization

Deserialization Example

Topic Objective

To show how to create a clone of the graph by deserializing it.

Lead-in

The preceding Serialization Example shows how to perform default serialization of a graph of objects, whose root is an ArrayList, with a serialized stream that is written to a FileStream in binary format.

class DeSerialize class DeSerialize

{{

public static void Main(String[] args) public static void Main(String[] args)

{{

}}

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The preceding Serialization Example shows how to perform default serialization of a graph of objects, whose root is an ArrayList, with a serialized stream that is written to a FileStream in binary format.

The following code sample shows how to create a clone of the graph by deserializing it. The root of the clone graph is called p.

using System; using System.IO;

using System.Collections;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

class DeSerialize

{

public static void Main(String[] args)

{

// open the filestream

FileStream s = File.OpenRead("foo.bin");

// create the formatter

BinaryFormatter b = new BinaryFormatter(); // deserialize

ArrayList p = (ArrayList) b.Deserialize(s); s.Close();

// print out the new object graph PrintValues(p);

}

(Code continued the following page.)

Соседние файлы в папке c#