When it comes to a class, the problem with saving
individual fields is that you could forget to save one of the fields. For
example, considering a Car class, if you don't save the Make information of
a Car object and retrieve or open the saved object on another computer, the
receiving user would miss some information and the car cannot be completely
identifiable. An alternative is to save the whole Car object.

Object serialization consists of saving a whole object
as one instead of its individual fields:

In other words, a variable declared from a class can be
saved to a stream and then the saved object can be retrieved later or on
another computer. The .NET Framework supports two types of object
serialization: binary and SOAP.

Practical
Learning: Introducing Serialization

Start Microsoft Visual Studio

Create a Windows Application named RealEstate1

To create a new form, on the main menu, click Projects -> Add
Windows Form...

Set the Name to PropertyEditor and click Add

Design the form as follows:

Control

Text

Name

Other Properties

Label

Property #:

TextBox

txtPropertyNumber

Modifiers: Public

Label

Property Type:

ComboBox

cbxPropertyTypes

Modifiers: PublicItems:
UnknownSingle FamilyTownhouseCondominium

Label

Address:

TextBox

txtAddress

Modifiers: Public

Label

City:

TextBox

txtCity

Modifiers: Public

Label

State:

ComboBox

cbxStates

Modifiers: PublicItems:DCMD
PAVAWV

Label

ZIP Code:

TextBox

txtZIPCode

Modifiers: Public

Label

Bedrooms:

TextBox

0

txtBedrooms

Modifiers: Public

Label

Bathrooms:

TextBox

1.0

txtBathrooms

Modifiers: Public

Label

Market Value:

TextBox

0.00

txtMarketValue

Modifiers: Public

Button

OK

btnOK

DialogResult: OK

Button

Cancel

btnCancel

DialogResult: Cancel

Form

FormBorderStyle:

FixedDialog

Text:

Altair Realtors - Property Editor

StartPosition:

CenterScreen

AcceptButton:

btnOK

CancelButton:

btnCancel

MaximizeBox:

False

MinimizeBox:

False

ShowInTaskBar:

False

In the Solution Explorer, right-click Form1.cs and click Rename

Type AltairRealtor.cs and press Enter twice (to display that
form)

Design the form as follows:

Control

Text

Name

Label

Property #:

TextBox

txtPropertyNumber

Button

Open

btnOpen

Label

Property Type:

TextBox

txtPropertyType

Label

Address:

TextBox

txtAddress

Label

City:

TextBox

txtCity

Label

State:

TextBox

txtState

Label

ZIP Code:

TextBox

txtZIPCode

Label

Bedrooms:

TextBox

0

txtBedrooms

Label

Bathrooms:

TextBox

1.0

txtBathrooms

Label

Market Value:

TextBox

0.00

txtMarketValue

Button

&New Property...

btnNewProperty

Button

Close

btnClose

Form

FormBorderStyle:

FixedDialog

Text:

Altair Realtors - Property Editor

StartPosition:

CenterScreen

Save the form

Serialization

Binary serialization works by processing an object
rather than streaming its individual member variables. This means that, to
use it, you define an object and initialize it, or "fill" it, with the
necessary values and any information you judge necessary. This creates a
"state" of the object. It is this state that you prepare to serialize. When
you save the object, it is converted into a stream.

To perform binary serialization, there are a few steps
you must follow. When creating the class whose objects would be serialized,
start it with the [Serializable] attribute. Here is an example:

Before serializing an object, you should reference the
System.Runtime.Serialization.Formatters.Binary namespace. The class
responsible for binary serialization is called BinaryFormatter. This
class is equipped with two constructors. The default constructor is used to
simply create an object.

After declaring the variable, to actually serialize an
object, call the Serialize() method of the BinaryFormatter
class. The method is overloaded with two versions. One of the versions of
this method uses the following syntax:

public void Serialize(Stream serializationStream, object graph);

The first argument to this method must be an object of a
Stream-based class, such as a FileStream object. The second
argument must be the object to serialize. This means that, before calling
this method, you should have built the object.

To create a new class, on the main menu, click Project -> Add
Class...

Set the Name to SampleProperty and click Add

Change the file as follows:

using System;
using System.Collections.Generic;
using System.Text;
namespace RealEstate1
{
[Serializable]
public class SampleProperty
{
public string PropertyNumber;
public string PropertyType;
public string Address;
public string City;
public string State;
public int ZIPCode;
public short Bedrooms;
public float Bathrooms;
public double MarketValue;
}
}

Execute the application and continuously click the New Property
button to create the following properties (let the computer specify the
property number):

Property Type

Address

City

State

ZIP Code

Beds

Baths

Market Value

Single Family

11604 Aldora Avenue

Baltimore

MD

21205

5

3.5

325650

Townhouse

495 Parker House Terrace

Gettysburg

WV

26201

3

2.5

225500

Condominium

5900 24th Street NW #812

Washington

DC

20008

1

1.0

388665

Single Family

6114 Costinha Avenue

Martinsburg

WV

25401

4

3.5

325000

Condominium

10710 Desprello Street #10D

Rockville

MD

20856

1

1.0

528445

Close the form and return to your programming environment

De-Serialization

As serialization is the process of storing an object to
a medium, the opposite, serialization is used to retrieve an object from a
stream. To support this, the BinaryFormatter class is equipped with
the Deserialize() method. Like Serialize(), the
Deserialize() method is overloaded with two versions. One of them uses
the following syntax:

public object Deserialize(Stream serializationStream);

This method takes as argument a Stream-based
object, such as a FileStream variable, that indicates where the file
is located. The Deserialize() method returns an Object object.
As a goal, you want the Deserialize() method to produce the type of
object that was saved so you can retrieve the values that the returned
object holds. Because the method returns an Object value, you must
cast the returned value to the type of your class.

Once the Deserialize() method has returned the
desired object, you can access its values. Here is an example:

Execute the application and try opening a previously save property
using its number

Close the form and return to your programming environment

Details on Serialization

Partial Serialization

In the examples we have used so far, we were saving the
whole object. You can make it possible to save only some parts of the class.
When creating a class, you can specify what fields would be serialized and
which ones would not be. To specify that a member cannot be saved, you can
mark it with the [NonSerialized] attribute. Here is an example:

[Serializable]
public class Car
{
public string Make;
public string Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
public decimal Value;
public uint Year;
public byte Color;
}

After creating the class, you can declare a variable of
it and serialize it, using either the binary or the SOAP approach. You can
then retrieve the object and its values, using any of the techniques we
learned earlier.

Implementing a Custom Serialized Class

To support serialization, the .NET Framework provides
the ISerializable interface. You can create a class that implements
this interface to customize the serialization process. Even if you plan to
use this interface, the class you create must be marked with the
[Serializable] attribute.

.NET Built-In Serialized Classes

The .NET Framework is filled with many classes ready for
serialization. To know that a class is ready for serialization, when viewing
its documentation either in the MSDN web site or in the help documentation,
check that it is marked with the [SerializableAttribute]. Here is an
example of such as class:

Some of these classes provide the properties and methods
to create an object and directly save it. For some other classes, you must
first create a class, mark it with the [Serializable] attribute,
build an object of it, and then pass it to the .NET class.