|
C# Serialization |
|
Object Serialization and De-Serialization |
|
|
Consider the following program:
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public class Exercise
{
static int Main(string[] args)
{
var Make = "Ford";
var Model = "Escort";
var Year = 1998;
var Color = 1;
var stmCar = new FileStream("Car1.car", FileMode.Create);
var bnwCar = new BinaryWriter(stmCar);
try
{
bnwCar.Write(Make);
bnwCar.Write(Model);
bnwCar.Write(Year);
bnwCar.Write(Color);
}
finally
{
bnwCar.Close();
stmCar.Close();
}
return 0;
}
}
This is an example of the techniques we have used in
previous lessons to save individual data of primitive types:
The values can be retrieved with the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public class Exercise
{
static int Main(string[] args)
{
var stmCar = new FileStream("Car1.car", FileMode.Open);
var bnrCar = new BinaryReader(stmCar);
try
{
Console.WriteLine("Make: {0}", bnrCar.ReadString());
Console.WriteLine("Model: {0}", bnrCar.ReadString());
Console.WriteLine("Year: {0}", bnrCar.ReadUInt32());
Console.Write("Color: ");
byte clr = bnrCar.ReadByte();
switch (clr)
{
case 1:
Console.WriteLine("Black");
break;
case 2:
Console.WriteLine("Gray");
break;
case 3:
Console.WriteLine("White");
break;
case 4:
Console.WriteLine("Red");
break;
case 5:
Console.WriteLine("Blue");
break;
}
}
finally
{
bnrCar.Close();
stmCar.Close();
}
return 0;
}
}
This would produce:
Make: Ford
Model: Escort
Year: 1998
Color: Black
Press any key to continue . . .
In the same way, we learned to save the individual
fields of a class:
Here is an example:
using System;
using System.IO;
public class Car
{
public string Make = "Toyota";
public string Model = "Corolla";
public uint Year = 2002;
public byte Color = 2;
}
public class Exercise
{
static int Main(string[] args)
{
var vehicle = new Car();
var stmCar = File.Create("Car2.car");
var bnwCar = new BinaryWriter(stmCar);
try
{
bnwCar.Write(vehicle.Model);
bnwCar.Write(vehicle.Year);
bnwCar.Write(vehicle.Color);
}
finally
{
bnwCar.Close();
stmCar.Close();
}
return 0;
}
}
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.
Application:
Introducing Serialization
|
|
- Start Microsoft Visual Studio and create a Console Application named
GeorgetownDryCleaningServices7
- To save the project, on the Standard toolbar, click the Save All
button
- Accept all the defaults and click Save
- To create a new class, in the Solution Explorer, right-click
GeorgetownDryCleaningServices7 -> Add -> Class...
- Set the Name to BusinessManagement and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace GeorgetownDryCleaningServices7
{
public static class BusinessManagement
{
public static void HireEmployee()
{
FileStream fsEmployee = null;
BinaryWriter bwEmployee = null;
// Ask the clerk to enter an employee number
// using the format 00-000
Console.Write("Enter Employee Number (00-000): ");
string emplNumber = Console.ReadLine();
string strPath = @"C:\Georgetown Cleaning Services\Employees\" +
@"\" + emplNumber + ".gce";
if (File.Exists(strPath))
{
Console.Write("\nEither the employee has already been hired, ");
Console.WriteLine("or there is already another " +
"employee with that number.");
return;
}
else // If no employee with that number was found, create it
{
try
{
// If there is not yet a directory
// named Employees, then create it
Directory.CreateDirectory(@"C:\Georgetown Cleaning " +
"Services\\Employees");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("The folder could not be created");
}
try
{
fsEmployee = File.Create(strPath);
bwEmployee = new BinaryWriter(fsEmployee);
Console.Write("Enter Employee First Name: ");
string emplFName = Console.ReadLine();
Console.Write("Enter Employee Last Name: ");
string emplLName = Console.ReadLine();
Console.Write("Enter Hourly Salary: ");
double emplSalary = double.Parse(Console.ReadLine());
// The minimum salary in this company is 7.50
if (emplSalary < 7.50D)
emplSalary = 7.50D;
bwEmployee.Write(emplNumber);
bwEmployee.Write(emplFName);
bwEmployee.Write(emplLName);
bwEmployee.Write(emplSalary);
}
finally
{
bwEmployee.Close();
fsEmployee.Close();
}
}
Console.WriteLine();
}
}
}
- Access the Program.cs file and change it as follows:
using System;
namespace GeorgetownDryCleaningServices7
{
public static class Program
{
static int Main(string[] args)
{
var answer = '0';
do
{
try
{
Console.WriteLine("What do you want to do?");
Console.WriteLine("0. Quit");
Console.WriteLine("1. Hire a new employee");
Console.WriteLine("2. Process a payroll");
Console.Write("Your Choice: ");
answer = char.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Invalid Answer!");
}
switch (answer)
{
case '1':
BusinessManagement.HireEmployee();
break;
case '2':
break;
default:
break;
}
} while (answer == '1' || answer == '2');
Console.WriteLine();
return 0;
}
}
}
- Execute the application and test it. Here is an example:
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 86-025
Enter Employee First Name: Anne
Enter Employee Last Name: Harang
Enter Hourly Salary: 6.75
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 42-713
Enter Employee First Name: Peter
Enter Employee Last Name: Lansome
Enter Hourly Salary: 12.45
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 29-368
Enter Employee First Name: Gertrude
Enter Employee Last Name: Monay
Enter Hourly Salary: 10.85
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 0
Press any key to continue . . .
- Close the DOS window
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:
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
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. In the previous lessons, we saw how to create
Stream objects (for example using the FileStream class).
The second argument must be the object to serialize.
This means that, before calling this method, you should have built the
object.
Here is an example:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
public class Exercise
{
static int Main(string[] args)
{
var vehicle = new Car();
vehicle.Make = "Lexus";
vehicle.Model = "LS";
vehicle.Year = 2007;
vehicle.Color = 4;
var stmCar = new FileStream("Car3.car", FileMode.Create);
var bfmCar = new BinaryFormatter();
bfmCar.Serialize(stmCar, vehicle);
return 0;
}
}
Application:
Serializing an Object
|
|
- To create a new class, in the Class View, right-click
GeorgetownDryCleaningServices7 -> Add -> Class...
- Set the Name to PayrollInformation and click OK
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices7
{
[Serializable]
public class PayrollInformation
{
private string number;
private string fname;
private string lname;
private double salary;
private DateTime start;
public string EmployeeNumber
{
get { return this.number; }
set { this.number = value; }
}
public string firstName
{
get { return this.fname; }
set { this.fname = value; }
}
public string lastName
{
get { return this.lname; }
set { this.lname = value; }
}
public double HourlySalary
{
get { return this.salary; }
set { this.salary = value; }
}
public DateTime StartPeriod
{
get { return this.start; }
set { this.start = value; }
}
public DateTime EndPeriod
{
get { return start.AddDays(13D); }
}
public double Week1Monday;
public double Week1Tuesday;
public double Week1Wednesday;
public double Week1Thursday;
public double Week1Friday;
public double Week2Monday;
public double Week2Tuesday;
public double Week2Wednesday;
public double Week2Thursday;
public double Week2Friday;
public double RegularHours;
public double OvertimeHours;
public double RegularAmount;
public double OvertimeAmount;
public double TotalEarnings;
}
}
- Access the BusinessManagement.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace GeorgetownDryCleaningServices7
{
public static class BusinessManagement
{
public static void HireEmployee()
{
FileStream fsEmployee = null;
BinaryWriter bwEmployee = null;
// Ask the clerk to enter an employee number
// using the format 00-000
Console.Write("Enter Employee Number (00-000): ");
string emplNumber = Console.ReadLine();
string strPath = @"C:\Georgetown Cleaning " +
@"Services\Employees\" +
@"\" + emplNumber + ".gce";
if (File.Exists(strPath))
{
Console.Write("\nEither the employee has " +
"already been hired, ");
Console.WriteLine("or there is already another " +
"employee with that number.");
return;
}
// If no employee with that number
// was found, create it
else
{
try
{
// If there is not yet a directory named
// Employees, then create it
Directory.CreateDirectory(@"C:\Georgetown " +
@"Cleaning Services\Employees");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("The folder could " +
"not be created");
}
try
{
fsEmployee = File.Create(strPath);
bwEmployee = new BinaryWriter(fsEmployee);
Console.Write("Enter Employee First Name: ");
string emplFName = Console.ReadLine();
Console.Write("Enter Employee Last Name: ");
string emplLName = Console.ReadLine();
Console.Write("Enter Hourly Salary: ");
double emplSalary =
double.Parse(Console.ReadLine());
// The minimum salary in this company is 7.50
if (emplSalary < 7.50D)
emplSalary = 7.50D;
bwEmployee.Write(emplNumber);
bwEmployee.Write(emplFName);
bwEmployee.Write(emplLName);
bwEmployee.Write(emplSalary);
}
finally
{
bwEmployee.Close();
fsEmployee.Close();
}
}
Console.WriteLine();
}
public static void CreatePayroll()
{
FileStream fsPayroll = null;
BinaryReader brPayroll = null;
DateTime dteStartDate;
PayrollInformation payroll =
new PayrollInformation();
double monday1 = 0.00D, tuesday1 = 0.00D,
wednesday1 = 0.00D, thursday1 = 0.00D,
friday1 = 0.00D, monday2 = 0.00D,
tuesday2 = 0.00D, wednesday2 = 0.00D,
thursday2 = 0.00D, friday2 = 0.00D;
double totalHoursWeek1 = 0.00D,
totalHoursWeek2 = 0.00D;
double regHours1 = 0.00D, regHours2 = 0.00D,
ovtHours1 = 0.00, ovtHours2 = 0.00;
double regAmount1 = 0.00D, regAmount2 = 0.00D,
ovtAmount1 = 0.00D, ovtAmount2 = 0.00D;
double regularHours = 0.00D, overtimeHours = 0.00D;
double regularAmount = 0.00D,
overtimeAmount = 0.00D,
totalEarnings = 0.00D;
Console.Write("Enter Employee Number: ");
string emplNumber = Console.ReadLine();
string strEmployeePath = @"C:\Georgetown " +
@"Cleaning Services\Employees\" +
@"\" + emplNumber + ".gce";
if (!File.Exists(strEmployeePath))
{
Console.WriteLine("There is no employee with " +
"that number in our records");
return;
}
// If an employee with that number was found,
// continue with the payroll
else {
try
{
fsPayroll = new FileStream(strEmployeePath,
FileMode.Open,
FileAccess.Read);
brPayroll = new BinaryReader(fsPayroll);
payroll.EmployeeNumber = brPayroll.ReadString();
payroll.firstName = brPayroll.ReadString();
payroll.lastName = brPayroll.ReadString();
payroll.HourlySalary = brPayroll.ReadDouble();
Console.WriteLine("\n------------------------" +
"------------------------");
Console.WriteLine("Employee #: {0}",
payroll.EmployeeNumber);
Console.WriteLine("Full Name: {0}, {1}",
payroll.firstName,
payroll.lastName);
Console.WriteLine("Hourly Salary: {0:C}",
payroll.HourlySalary);
Console.WriteLine("-------------------------" +
"-----------------------\n");
}
finally
{
brPayroll.Close();
fsPayroll.Close();
}
try
{
do
{
Console.Write("Enter Payroll Start " +
"Date (mm/dd/yyyy): ");
dteStartDate =
DateTime.Parse(Console.ReadLine());
if (dteStartDate.DayOfWeek !=
DayOfWeek.Sunday)
{
Console.WriteLine("Invalid Date Entry");
Console.WriteLine("Payrolls start " +
"on a Sunday");
}
} while (dteStartDate.DayOfWeek !=
DayOfWeek.Sunday);
payroll.StartPeriod = dteStartDate;
}
catch (FormatException)
{
Console.WriteLine("Invalid Date Entry");
}
}
// Retrieve the value of each day worked
Console.WriteLine("\nEnter the time worked " +
"for each day (0.00)");
Console.WriteLine("=-= Week 1 =-=");
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(1).ToString("D"));
monday1 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(2).ToString("D"));
tuesday1 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(3).ToString("D"));
wednesday1 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(4).ToString("D"));
thursday1 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(5).ToString("D"));
friday1 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
Console.WriteLine("=-= Week 2 =-=");
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(8).ToString("D"));
monday2 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(9).ToString("D"));
tuesday2 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(10).ToString("D"));
wednesday2 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(11).ToString("D"));
thursday2 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
try
{
Console.Write("{0}: ",
payroll.StartPeriod.AddDays(12).ToString("D"));
friday2 = double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("You typed an invalid value");
}
// Calculate the total number of hours for each week
totalHoursWeek1 = monday1 + tuesday1 + wednesday1 +
thursday1 + friday1;
totalHoursWeek2 = monday2 + tuesday2 + wednesday2 +
thursday2 + friday2;
// The overtime is paid time and half
double ovtSalary = payroll.HourlySalary * 1.5D;
// If the employee worked under 40 hours,
// there is no overtime
if (totalHoursWeek1 < 40)
{
regHours1 = totalHoursWeek1;
regAmount1 = payroll.HourlySalary * regHours1;
ovtHours1 = 0.00D;
ovtAmount1 = 0.00D;
} // If the employee worked over 40 hours,
// calculate the overtime
else if (totalHoursWeek1 >= 40)
{
regHours1 = 40;
regAmount1 = payroll.HourlySalary * 40;
ovtHours1 = totalHoursWeek1 - 40;
ovtAmount1 = ovtHours1 * ovtSalary;
}
if (totalHoursWeek2 < 40)
{
regHours2 = totalHoursWeek2;
regAmount2 = payroll.HourlySalary * regHours2;
ovtHours2 = 0.00D;
ovtAmount2 = 0.00D;
}
else if (totalHoursWeek2 >= 40)
{
regHours2 = 40;
regAmount2 = payroll.HourlySalary * 40;
ovtHours2 = totalHoursWeek2 - 40;
ovtAmount2 = ovtHours2 * ovtSalary;
}
regularHours = regHours1 + regHours2;
overtimeHours = ovtHours1 + ovtHours2;
regularAmount = regAmount1 + regAmount2;
overtimeAmount = ovtAmount1 + ovtAmount2;
totalEarnings = regularAmount + overtimeAmount;
payroll.Week1Monday = monday1;
payroll.Week1Tuesday = tuesday1;
payroll.Week1Wednesday = wednesday1;
payroll.Week1Thursday = thursday1;
payroll.Week1Friday = friday1;
payroll.Week2Monday = monday2;
payroll.Week2Tuesday = tuesday2;
payroll.Week2Wednesday = wednesday2;
payroll.Week2Thursday = thursday2;
payroll.Week2Friday = friday2;
payroll.RegularHours = regularHours;
payroll.OvertimeHours = overtimeHours;
payroll.RegularAmount = regularAmount;
payroll.OvertimeAmount = overtimeAmount;
payroll.TotalEarnings = totalEarnings;
ShowPayroll(payroll);
Console.Write("Do you want to save " +
"the payroll (y/n): ");
string strAnswer = Console.ReadLine();
if (strAnswer.ToUpper() == "Y")
SavePayroll(payroll);
}
public static void SavePayroll(PayrollInformation pay)
{
// We will need this value to create the
// name of the payroll file
string strMonth = "0", strDay = "0", strYear = "0";
// We want the month and day to include 0 if necessary
strMonth = pay.StartPeriod.Month.ToString();
if (pay.StartPeriod.Month < 10)
strMonth = "0" + pay.StartPeriod.Month.ToString();
strDay = pay.StartPeriod.Day.ToString();
if (pay.StartPeriod.Day < 10)
strDay = "0" + pay.StartPeriod.Day.ToString();
strYear = pay.StartPeriod.Year.ToString();
string strPayrollFilename = @"C:\Georgetown " +
@"Cleaning Services\Payrolls\" +
@"\" + pay.lastName[0] +
pay.firstName[0] +
strMonth + strDay +
strYear + ".epr";
try
{
// If there is not yet a directory for the
// payrolls, then create it
Directory.CreateDirectory(@"C:\Georgetown Cleaning " +
@"Services\Payrolls");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("The employee payroll file " +
"could not be created");
}
if (File.Exists(strPayrollFilename))
{
Console.WriteLine("The employee's payroll " +
"for that period exists already");
}
FileStream fsEmployeePayroll =
new FileStream(strPayrollFilename,
FileMode.Create);
BinaryFormatter bfEmployeePayroll =
new BinaryFormatter();
bfEmployeePayroll.Serialize(fsEmployeePayroll, pay);
fsEmployeePayroll.Close();
}
public static void ViewPayroll()
{
}
public static void ShowPayroll(PayrollInformation payed)
{
Console.WriteLine("\n=============================" +
"===================");
Console.WriteLine("=$= Payroll summary =$=");
Console.WriteLine("-------------------------------" +
"-----------------");
Console.WriteLine("Employee #: {0}",
payed.EmployeeNumber);
Console.WriteLine("Full Name: {0}, {1}",
payed.firstName, payed.lastName);
Console.WriteLine("Hourly Salary: {0:C}",
payed.HourlySalary);
Console.WriteLine("Start Period: {0:D}",
payed.StartPeriod);
Console.WriteLine("End Period: {0:D}",
payed.EndPeriod);
Console.WriteLine("--------------------------------" +
"----------------");
Console.WriteLine(" Monday Tuesday Wednesday " +
"Thursday Friday");
Console.WriteLine("Week 1: {0:F} {1:F} " +
"{2:F} {3:F} {4:F}",
payed.Week1Monday, payed.Week1Tuesday,
payed.Week1Wednesday, payed.Week1Thursday,
payed.Week1Friday);
Console.WriteLine("Week 2: {0:F} {1:F} " +
"{2:F} {3:F} {4:F}",
payed.Week2Monday, payed.Week2Tuesday,
payed.Week2Wednesday, payed.Week2Thursday,
payed.Week2Friday);
Console.WriteLine("-------------------------------" +
"-----------------");
Console.WriteLine("Monetary Summary");
Console.WriteLine(" Hours Amount");
Console.WriteLine("Regular: {0,6} {1,6}",
payed.RegularHours.ToString("F"),
payed.RegularAmount.ToString("F"));
Console.WriteLine("Overtime: {0,6} {1,6}",
payed.OvertimeHours.ToString("F"),
payed.OvertimeAmount.ToString("F"));
Console.WriteLine("-------------------------------" +
"-----------------");
Console.WriteLine("Net Pay: {0:F}",
payed.TotalEarnings);
Console.WriteLine("===============================" +
"=================\n");
}
}
}
- Access the Program.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GeorgetownDryCleaningServices7
{
public static class Program
{
static int Main(string[] args)
{
var answer = '0';
Console.WriteLine("========================" +
"========================");
Console.WriteLine("Georgetown Cleaning Services");
Console.WriteLine("========================" +
"========================");
do
{
try
{
Console.WriteLine("\nWhat do you want to do?");
Console.WriteLine("0. Quit");
Console.WriteLine("1. Hire a new employee");
Console.WriteLine("2. Process a payroll");
Console.WriteLine("3. View an employee's payroll");
Console.Write("Your Choice: ");
answer = char.Parse(Console.ReadLine());
Console.WriteLine();
}
catch (FormatException)
{
Console.WriteLine("Invalid Answer!");
}
switch (answer)
{
case '1':
BusinessManagement.HireEmployee();
break;
case '2':
BusinessManagement.CreatePayroll();
break;
case '3':
BusinessManagement.ViewPayroll();
break;
default:
break;
}
} while( (answer == '1') ||
(answer == '2') ||
(answer == '3') );
return 0;
}
}
}
- Execute the application and test it. Here is an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 2
Enter Employee Number: 29-368
------------------------------------------------
Employee #: 29-368
Full Name: Gertrude, Monay
Hourly Salary: $10.85
------------------------------------------------
Enter Payroll Start Date (mm/dd/yyyy): 11/12/05
Invalid Date Entry
Payrolls start on a Sunday
Enter Payroll Start Date (mm/dd/yyyy): 11/12/06
Enter the time worked for each day (0.00)
=-= Week 1 =-=
Monday, November 13, 2006: 8.00
Tuesday, November 14, 2006: 8.50
Wednesday, November 15, 2006: 9.50
Thursday, November 16, 2006: 8
Friday, November 17, 2006: 8.50
=-= Week 2 =-=
Monday, November 20, 2006: 6.50
Tuesday, November 21, 2006: 7.00
Wednesday, November 22, 2006: 8
Thursday, November 23, 2006: 6.00
Friday, November 24, 2006: 7.00
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 29-368
Full Name: Gertrude, Monay
Hourly Salary: $10.85
Start Period: Sunday, November 12, 2006
End Period: Saturday, November 25, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 8.50 9.50 8.00 8.50
Week 2: 6.50 7.00 8.00 6.00 7.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 74.50 808.33
Overtime: 2.50 40.69
------------------------------------------------
Net Pay: 849.01
================================================
Do you want to save the payroll (y/n): Y
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 0
Press any key to continue . . .
- Close the DOS window
- Execute the application again and process another payroll. Here is
an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 2
Enter Employee Number: 86-025
------------------------------------------------
Employee #: 86-025
Full Name: Anne, Harang
Hourly Salary: $7.50
------------------------------------------------
Enter Payroll Start Date (mm/dd/yyyy): 11/26/2006
Enter the time worked for each day (0.00)
=-= Week 1 =-=
Monday, November 27, 2006: 8.00
Tuesday, November 28, 2006: 6.50
Wednesday, November 29, 2006: 8.50
Thursday, November 30, 2006: 8.00
Friday, December 01, 2006: 8.00
=-= Week 2 =-=
Monday, December 04, 2006: 9.00
Tuesday, December 05, 2006: 8.50
Wednesday, December 06, 2006: 8.00
Thursday, December 07, 2006: 9.50
Friday, December 08, 2006: 8.00
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 86-025
Full Name: Anne, Harang
Hourly Salary: $7.50
Start Period: Sunday, November 26, 2006
End Period: Saturday, December 09, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 6.50 8.50 8.00 8.00
Week 2: 9.00 8.50 8.00 9.50 8.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 79.00 592.50
Overtime: 3.00 33.75
------------------------------------------------
Net Pay: 626.25
================================================
Do you want to save the payroll (y/n): y
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 0
Press any key to continue . . .
- Close the DOS window
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:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
class Program
{
static int Main(string[] args)
{
var stmCar = new FileStream("Car3.car", FileMode.Open);
var bfmCar = new BinaryFormatter();
var vehicle = (Car)bfmCar.Deserialize(stmCar);
Console.WriteLine("Make: {0}", vehicle.Make);
Console.WriteLine("Model: {0}", vehicle.Model);
Console.WriteLine("Year: {0}", vehicle.Year);
Console.Write("Color: ");
byte clr = vehicle.Color;
switch (clr)
{
case 1:
Console.WriteLine("Black");
break;
case 2:
Console.WriteLine("Gray");
break;
case 3:
Console.WriteLine("White");
break;
case 4:
Console.WriteLine("Red");
break;
case 5:
Console.WriteLine("Blue");
break;
}
stmCar.Close();
return 0;
}
}
Application:
De-Serializing an Object
|
|
- Access the BusinessManagement.cs file and implement the
ViewPayroll() method as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace GeorgetownDryCleaningServices7
{
public static class BusinessManagement
{
public static void HireEmployee()
{
. . . No Change
}
public static void CreatePayroll()
{
. . . No Change
}
public static void SavePayroll(PayrollInformation pay)
{
. . . No Change
}
public static void ViewPayroll()
{
string strEmplNumber, strFName, strLName;
string strMonth, strDay, strYear;
// Ask the clerk to enter an employee number
// using the format 00-000
Console.Write("Enter Employee Number (00-000): ");
strEmplNumber = Console.ReadLine();
string strFilename = @"C:\Georgetown Cleaning " +
@"Services\Employees\" +
@"\" + strEmplNumber + ".gce";
if (!File.Exists(strFilename))
{
Console.Write("There is no employee " +
"with that number.");
}
else
{
FileStream fsEmployee = null;
BinaryReader brEmployee = null;
try
{
// We need to formally open the file
// because we need the employees initials
fsEmployee = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
brEmployee = new BinaryReader(fsEmployee);
// Read the file, mainly to get the
// employee's name
strEmplNumber = brEmployee.ReadString();
strFName = brEmployee.ReadString();
strLName = brEmployee.ReadString();
}
finally
{
brEmployee.Close();
fsEmployee.Close();
}
Console.Write("Enter the start date of the " +
"payroll you want to see (mm/dd/yyyy): ");
DateTime dteStartDate =
DateTime.Parse(Console.ReadLine());
// We want the month and day to include 0 if necessary
strMonth = dteStartDate.Month.ToString();
if (dteStartDate.Month < 10)
strMonth = "0" + dteStartDate.Month.ToString();
strDay = dteStartDate.Day.ToString();
if (dteStartDate.Day < 10)
strDay = "0" + dteStartDate.Day.ToString();
strYear = dteStartDate.Year.ToString();
strFilename = @"C:\Georgetown Cleaning " +
@"Services\Payrolls\" +
@"\" + strLName[0] +
strFName[0] + strMonth +
strDay + strYear + ".epr";
if (!File.Exists(strFilename))
{
Console.Write("{0}, {1} doesn't have a " +
"payroll in that time frame",
strLName, strFName);
}
else
{
// Open the payroll and display it
FileStream fsPayroll =
new FileStream(strFilename,
FileMode.Open);
BinaryFormatter bfPayroll =
new BinaryFormatter();
PayrollInformation pay =
(PayrollInformation)bfPayroll.Deserialize(fsPayroll);
ShowPayroll(pay);
}
}
}
public static void ShowPayroll(PayrollInformation payed)
{
. . . No Change
}
}
}
- Execute the application and test it. Here is an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 3
Enter Employee Number (00-000): 29-368
Enter the start date of the payroll you want to see (mm/dd/yyyy): 11/12/2006
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 29-368
Full Name: Gertrude, Monay
Hourly Salary: $10.85
Start Period: Sunday, November 12, 2006
End Period: Saturday, November 25, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 8.50 9.50 8.00 8.50
Week 2: 6.50 7.00 8.00 6.00 7.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 74.50 808.33
Overtime: 2.50 40.69
------------------------------------------------
Net Pay: 849.01
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 3
Enter Employee Number (00-000): 86-025
Enter the start date of the payroll you want to see (mm/dd/yyyy): 11/26/06
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 86-025
Full Name: Anne, Harang
Hourly Salary: $7.50
Start Period: Sunday, November 26, 2006
End Period: Saturday, December 09, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 6.50 8.50 8.00 8.00
Week 2: 9.00 8.50 8.00 9.50 8.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 79.00 592.50
Overtime: 3.00 33.75
------------------------------------------------
Net Pay: 626.25
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 0
Press any key to continue . . .
- Close the DOS window
The .NET Framework supports another technique of
serialization referred to as SOAP (which stands for Simple Object Access
Protocol). This technique is related to XML but, although we haven't studied
XML, you don't need to know anything about it to use SOAP serialization.
Application:
Introducing SOAP Serialization
|
|
- Start a new Console Application named PropertyRental1
- To create a new class, on the main menu, click Project -> Add Class
- Set the Name to Property and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PropertyRental1
{
public enum TypeOfProperty
{
Appartment,
SingleFamily,
Townhouse,
Unknown
}
public enum Condition
{
Excellent,
Good,
NeedsRepair,
Unknown
}
[Serializable]
public class Property
{
private long propCode;
private TypeOfProperty tp;
private Condition cond;
private short beds;
private float baths;
private int levels;
private decimal val;
public long PropertyCode
{
get { return propCode; }
set { propCode = value; }
}
public TypeOfProperty PropertyType
{
get { return tp; }
set { tp = value; }
}
public Condition PropertyCondition
{
get { return cond; }
set { cond = value; }
}
public short Bedrooms
{
get { return beds; }
set { beds = value; }
}
public float Bathrooms
{
get { return (baths <= 0) ? 0.00f : baths; }
set { baths = value; }
}
public int Stories
{
get { return levels; }
set { levels = value; }
}
public decimal MonthlyRent
{
get { return (val <= 0) ? 0.00M : val; }
set { val = value; }
}
public Property()
{
Random rnd = new Random();
propCode = rnd.Next(100000, 999999);
tp = TypeOfProperty.Unknown;
cond = Condition.Unknown;
beds = 0;
baths = 0.0f;
levels = 0;
val = 0.00M;
}
}
}
- To create a new class, on the main menu, click Project -> Add Class
- Set the Name to PropertyListing and press Enter
- Change the file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PropertyRental1
{
[Serializable]
public class PropertyListing
{
private Property[] prop = new Property[100];
public Property this[int i]
{
get { return prop[i]; }
set { prop[i] = value; }
}
}
}
To serialize an object using SOAP, you follow the same
steps we reviewed for the binary serialization with one addition that you
must add a certain reference.
When creating the class whose objects would be
serialized, mark it with the [Serializable] attribute. Here is an
example:
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
To support SOAP serialization, the .NET Framework
provides the SoapFormatter class. This class is defined in the
System.Runtime.Serialization.Formatters.Soap namespace that is part of
the System.Runtime.Serialization.Formatters.Soap.dll assembly. In
order to use The SoapFormatter class, you must reference this
assembly. Then, you can create an object and initialize it as you see fit.
Before saving it, as always, create a Stream-based object that would
indicate the name (and location) of the file and the type of action to
perform. Then, declare a SoapFormatter variable using its default
constructor. To actually save the object, call the Serialize() method
of this class. This method uses the same syntax as that of the
BinaryFormatter class: it takes two arguments. The first is a
Stream-based object. The second is the object that needs to be serialized.
Here is an example:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
public static class Program
{
public static int Main(string[] args)
{
var vehicle = new Car();
vehicle.Make = "Volvo";
vehicle.Model = "S40";
vehicle.Year = 2006;
vehicle.Color = 3;
var stmCar =
new FileStream("Car4.car",
FileMode.Create);
var sopCar = new SoapFormatter();
sopCar.Serialize(stmCar, vehicle);
return 0;
}
}
Application:
Serializing With SOAP
|
|
- To add SOAP support to your project, on the main menu, click Project
-> Add Reference...
- In the Add Reference dialog box and in the .NET tab, scroll down and
select System.Runtime.Serialization.Formatters.Soap:
- Click OK
- Access the Program.cs file and change it as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace PropertyRental1
{
class Program
{
static PropertyListing CreateListing()
{
Random rnd = new Random();
Property prop = new Property();
PropertyListing listing = new PropertyListing();
prop = new Property();
// Create a few properties ready to be rented
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.SingleFamily;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 5;
prop.Bathrooms = 3.5f;
prop.Stories = 3;
prop.MonthlyRent = 2650;
listing[0] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.Townhouse;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 3;
prop.Bathrooms = 2.5f;
prop.Stories = 3;
prop.MonthlyRent = 1750;
listing[1] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.SingleFamily;
prop.PropertyCondition = Condition.Good;
prop.Bedrooms = 4;
prop.Bathrooms = 2.5f;
prop.Stories = 2;
prop.MonthlyRent = 2450;
listing[2] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.Appartment;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 1;
prop.Bathrooms = 1.0f;
prop.Stories = 1;
prop.MonthlyRent = 880;
listing[3] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.Townhouse;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 3;
prop.Bathrooms = 2.5f;
prop.Stories = 2;
prop.MonthlyRent = 1880;
listing[4] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.Appartment;
prop.PropertyCondition = Condition.Good;
prop.Bedrooms = 2;
prop.Bathrooms = 1.0f;
prop.Stories = 1;
prop.MonthlyRent = 1050;
listing[5] = prop;
// Since we don't yet have a complete list of properties
// Create some empty ones
for (int i = 5; i < 100; i++)
{
prop = new Property();
listing[i] = prop;
}
return listing;
}
static int Main()
{
PropertyListing props = CreateListing();
Property prop = new Property();
FileStream prpStream =
new FileStream("properties.rnt",
FileMode.Create);
SoapFormatter prpSoap = new SoapFormatter();
prpSoap.Serialize(prpStream, props);
for (int i = 0; i < 16; i++)
{
prop = props[i];
Console.WriteLine("{0}.----------------------------------", i + 1);
Console.WriteLine("Property #: {0}", prop.PropertyCode);
Console.WriteLine("Type: {0}", prop.PropertyType);
Console.WriteLine("Condition: {0}", prop.PropertyCondition);
Console.WriteLine("Bedrooms: {0}", prop.Bedrooms);
Console.WriteLine("Bathrooms: {0}", prop.Bathrooms);
Console.WriteLine("Stories: {0}", prop.Stories);
Console.WriteLine("Market Value: {0}\n", prop.MonthlyRent);
}
Console.WriteLine("======================================");
return 0;
}
}
}
- Execute the application
De-Serialization With SOAP
|
|
De-serialization in soap is performed exactly as done
for the binary de-serialization. To support it, the SoapFormatter
class is equipped with the Deserialize() method. This method uses the
same syntax as its equivalent of the BinaryFormatter class. The
approach to use it is also the same.
Here is an example:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
[Serializable]
public class Car
{
public string Make;
public string Model;
public uint Year;
public byte Color;
}
public static class Program
{
public static int Main(string[] args)
{
var stmCar = new FileStream("Car4.car", FileMode.Open);
var sopCar = new SoapFormatter();
var vehicle = (Car)sopCar.Deserialize(stmCar);
Console.WriteLine("Car Information");
Console.WriteLine("Make: {0}", vehicle.Make );
Console.WriteLine("Model: {0}", vehicle.Model);
Console.WriteLine("Year: {0}", vehicle.Year);
Console.Write("Color: ");
switch (vehicle.Color)
{
case 1:
Console.WriteLine("Black");
break;
case 2:
Console.WriteLine("Gray");
break;
case 3:
Console.WriteLine("White");
break;
case 4:
Console.WriteLine("Red");
break;
case 5:
Console.WriteLine("Blue");
break;
}
return 0;
}
}
Application:
Deserializing With SOAP
|
|
- To deserialize, change the contents of the Program.cs file as
follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace PropertyRental1
{
class Program
{
static int Main()
{
Property prop = new Property();
// Open the list/collection of properties
FileStream prpStream =
new FileStream("properties.rnt",
FileMode.Open);
SoapFormatter prpSoap = new SoapFormatter();
PropertyListing props =
(PropertyListing)prpSoap.Deserialize(prpStream);
prpStream.Close();
for (int i = 0; i < 16; i++)
{
prop = props[i];
Console.WriteLine("{0}.----------------------------------", i + 1);
Console.WriteLine("Property #: {0}", prop.PropertyCode);
Console.WriteLine("Type: {0}", prop.PropertyType);
Console.WriteLine("Condition: {0}", prop.PropertyCondition);
Console.WriteLine("Bedrooms: {0}", prop.Bedrooms);
Console.WriteLine("Bathrooms: {0}", prop.Bathrooms);
Console.WriteLine("Stories: {0}", prop.Stories);
Console.WriteLine("Market Value: {0}\n", prop.MonthlyRent);
}
Console.WriteLine("======================================");
return 0;
}
}
}
- Press Ctrl + F5 to execute the application
- After viewing the result, close the DOS window
- To apply an example of updating the file, change the contents of the
Program.cs file as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace PropertyRental1
{
class Program
{
static int Main()
{
Property prop = new Property();
// Open the list/collection of properties
FileStream prpStream =
new FileStream("properties.rnt",
FileMode.Open);
SoapFormatter prpSoap = new SoapFormatter();
// Get the list of properties and store it in an array
PropertyListing props =
(PropertyListing)prpSoap.Deserialize(prpStream);
// Close the stream while we are working on something else
prpStream.Close();
// To add a few properties, we will actually replace
// some "empty" properties whose placeholders we defined earlier
Random rnd = new Random();
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.Appartment;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 2;
prop.Bathrooms = 2.0f;
prop.Stories = 1;
prop.MonthlyRent = 1240;
props[7] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.SingleFamily;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 3;
prop.Bathrooms = 2.5f;
prop.Stories = 3;
prop.MonthlyRent = 1750;
props[8] = prop;
prop = new Property();
prop.PropertyCode = rnd.Next(100000, 999999);
prop.PropertyType = TypeOfProperty.SingleFamily;
prop.PropertyCondition = Condition.Good;
prop.Bedrooms = 5;
prop.Bathrooms = 3.5f;
prop.Stories = 3;
prop.MonthlyRent = 3475;
props[14] = prop;
prop = new Property();
prop.PropertyType = TypeOfProperty.Appartment;
prop.PropertyCondition = Condition.Excellent;
prop.Bedrooms = 2;
prop.Bathrooms = 1.0f;
prop.Stories = 1;
prop.MonthlyRent = 1275;
props[28] = prop;
// Reopen the stream
prpStream = new FileStream("properties.rnt",
FileMode.Create);
prpSoap = new SoapFormatter();
// Open the file and save it
prpSoap.Serialize(prpStream, props);
prpStream.Close();
// That's it
for (int i = 0; i < 16; i++)
{
prop = props[i];
Console.WriteLine("{0}.----------------------------------", i + 1);
Console.WriteLine("Property #: {0}", prop.PropertyCode);
Console.WriteLine("Type: {0}", prop.PropertyType);
Console.WriteLine("Condition: {0}", prop.PropertyCondition);
Console.WriteLine("Bedrooms: {0}", prop.Bedrooms);
Console.WriteLine("Bathrooms: {0}", prop.Bathrooms);
Console.WriteLine("Stories: {0}", prop.Stories);
Console.WriteLine("Market Value: {0}\n", prop.MonthlyRent);
}
Console.WriteLine("======================================");
return 0;
}
}
}
- Press Ctrl + F5 to execute the application
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. Here is
an example:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[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;
}
public class Exercise
{
static int Main(string[] args)
{
var vehicle = new Car();
vehicle.Make = "Lexus";
vehicle.Model = "LS";
vehicle.Year = 2007;
vehicle.Color = 4;
vehicle.Value = 28640M;
var stmCar = new FileStream("Car1.car", FileMode.Create);
var bfmCar = new BinaryFormatter();
bfmCar.Serialize(stmCar, vehicle);
return 0;
}
}
You can then retrieve the object and its values, using
any of the techniques we learned earlier. Here is an example:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[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;
}
public class Exercise
{
static int Main(string[] args)
{
var stmCar = new FileStream("Car1.car", FileMode.Open);
var bfmCar = new BinaryFormatter();
var vehicle = (Car)bfmCar.Deserialize(stmCar);
Console.WriteLine("Car Information");
Console.WriteLine("Make: {0}", vehicle.Make);
Console.WriteLine("Model: {0}", vehicle.Model);
Console.WriteLine("Year: {0}", vehicle.Year);
Console.Write("Color: ");
switch (vehicle.Color)
{
case 1:
Console.WriteLine("Black");
break;
case 2:
Console.WriteLine("Gray");
break;
case 3:
Console.WriteLine("White");
break;
case 4:
Console.WriteLine("Red");
break;
case 5:
Console.WriteLine("Blue");
break;
}
Console.WriteLine("Value: {0}\n", vehicle.Value);
return 0;
}
}
This would produce:
Car Information
Make: Lexus
Model: LS
Year: 2007
Color: Red
Value: 0
Press any key to continue . . .
Notice that the value of the Value field was not saved:
it holds the default value of its data type. This indicates that, you can
assign a value a [NonSerialized] field and save the object. The value
of that field would not be saved but the compiler would not throw an
exception.
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 [SerializableAttribute]
attribute, build an object of it, and then pass it to the .NET class.
|
|