Last Updated:

Serialization, or conversion to sequential form in .net

Serialization, or conversion to sequential form

Saving a complex data structure with related objects can become quite cumbersome when using the File and Stream classes. You must save all individual fields to disk. In doing so, you need to remember which of the fields belongs to which object, and which instance of the class is associated with other instances of objects. When you restore, you must recreate the order of the fields and the object references.

The .NET Framework provides a serialization technology (conversion to a sequential form) that does all of the above on its own. Serialization converts objects such as classes, structures, and arrays into a stream of bytes. When converted from a serial form to a parallel form, the byte stream is converted back to objects. Serialization and conversion from serial to parallel form can be done on different machines if they are running the common language runtime (CLR).

Objects can be converted to sequential form without the use of specially written code, because, as we have seen, at run time it is possible to query the metadata of an object, which makes it possible to know the distribution of memory occupied by this object. To inform the wireframe that a class can be converted to a sequential form, you must mark the class with the System::Serializable attribute.

Any field or property that does not want to be converted to a sequential form can be marked with the System::NonSerialized attribute. For example, fields that are cached variables should not be converted to sequential form. All you need to do is mark the class with an attribute that indicates that the class can be converted to a sequential form. And then there's no need for any other code that converts to a sequential form.

The Serialization sample shows how to apply the conversion to a sequential form to learn the HotelBroker class in the Hotel assembly. The Serializable attribute is used in the Definition of the HotelBroker class. The Serializable serialization attribute also applies to all classes that are used by the HotelBroker class or derived from the Base Classes of the HotelBroker class: 

BrokerHotelHotelReservationReservable, and Reservation, because when serializing, HotelBroker must also be converted to a sequential form. If any of these classes were not marked with an attribute, an exception might occur at run time when attempting to serialize an object of that type.

[Serializable]
// [Serializable]
public_gc class HotelBroker:
// garbage collector class HotelBroker:
public broker,
// public Broker
public IHotellInfo,
public IHotelAdmin,
public IHotelReservation
{
private: // private
const int MAXDAY; // constant
const int MAXUNIT; // constant
[NonSerialized] ArrayList *cities;
// [Non-serializable]
};
[Serializable]
// [Serializable]
public _gc class Hotel:
public Reservable
// garbage collector class Hotel:
Reservable
{
};
[Serializable]
// [Serializable]
public _gc class HotelReservation:
public reservation
// public garbage collector class HotelReservation:
Reservation
{
};
[Serializable]
// [Serializable]
public_gc_abstract class Reservable
// garbage collector - abstract class Reservable
{
};
[Serializable]
// [Serializable]
public _gc _abstract class Reservation
// garbage collector - abstract class Reservation
{
};
[Serializable]
// [Serializable]
public_gc_abstract class Broker
// garbage collector - Broker abstract class
{
};

The cities field was marked as NonSerialized because the name of the city where the hotel is located is retained along with the hotel names converted to a sequential form. Therefore, it can be restored using the modified AddCity method.

The cities field would be empty after converting the HotelBroker class from a sequential form to a parallel form because it has not been saved.

private: // private
void AddCity(String *city) // (String *city)
{
if (cities == 0) // if (cities == 0)
{
cities = new ArrayList; // cities
lEnumerator *pEnum = units › GetEnumerator();
while (pEnum › MoveNext())
{
Hotel *h = // Hotel
dynamic_cast<Hotel *>(pEnum › Current);
AddCity(h>City); // City
}
}
// check if city already on list, add if not
// check if the city is already in the list, add if not
if (!cities › Contains(city))
// if (! cities › Contain (city))
cities › Add(city);
// cities › Add (city);
}